mirror of
https://github.com/Takiiiiiiii/strato.git
synced 2025-07-17 08:46:39 +00:00
Add adrenotools direct mapping support
This commit is contained in:
@ -33,7 +33,7 @@ namespace skyline::gpu::memory {
|
||||
return pointer;
|
||||
}
|
||||
|
||||
MemoryManager::MemoryManager(const GPU &pGpu) : gpu(pGpu) {
|
||||
MemoryManager::MemoryManager(GPU &pGpu) : gpu{pGpu} {
|
||||
auto instanceDispatcher{gpu.vkInstance.getDispatcher()};
|
||||
auto deviceDispatcher{gpu.vkDevice.getDispatcher()};
|
||||
VmaVulkanFunctions vulkanFunctions{
|
||||
@ -143,4 +143,34 @@ namespace skyline::gpu::memory {
|
||||
|
||||
return Image(vmaAllocator, image, allocation);
|
||||
}
|
||||
|
||||
ImportedBuffer MemoryManager::ImportBuffer(span<u8> cpuMapping) {
|
||||
if (!gpu.traits.supportsAdrenoDirectMemoryImport)
|
||||
throw exception("Cannot import host buffers without adrenotools import support!");
|
||||
|
||||
if (!adrenotools_import_user_mem(&gpu.adrenotoolsImportMapping, cpuMapping.data(), cpuMapping.size()))
|
||||
throw exception("Failed to import user memory");
|
||||
|
||||
auto buffer{gpu.vkDevice.createBuffer(vk::BufferCreateInfo{
|
||||
.size = cpuMapping.size(),
|
||||
.usage = vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst | vk::BufferUsageFlagBits::eUniformTexelBuffer | vk::BufferUsageFlagBits::eStorageTexelBuffer | vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eIndirectBuffer | vk::BufferUsageFlagBits::eTransformFeedbackBufferEXT,
|
||||
.sharingMode = vk::SharingMode::eExclusive
|
||||
})};
|
||||
|
||||
auto memory{gpu.vkDevice.allocateMemory(vk::MemoryAllocateInfo{
|
||||
.allocationSize = cpuMapping.size(),
|
||||
.memoryTypeIndex = gpu.traits.hostVisibleCoherentCachedMemoryType,
|
||||
})};
|
||||
|
||||
if (!adrenotools_validate_gpu_mapping(&gpu.adrenotoolsImportMapping))
|
||||
throw exception("Failed to validate GPU mapping");
|
||||
|
||||
gpu.vkDevice.bindBufferMemory2({vk::BindBufferMemoryInfo{
|
||||
.buffer = *buffer,
|
||||
.memory = *memory,
|
||||
.memoryOffset = 0
|
||||
}});
|
||||
|
||||
return ImportedBuffer{cpuMapping, std::move(buffer), std::move(memory)};
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,30 @@ namespace skyline::gpu::memory {
|
||||
using Buffer::Buffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A buffer that directly owns it's own memory
|
||||
*/
|
||||
struct ImportedBuffer : public span<u8> {
|
||||
vk::raii::Buffer vkBuffer;
|
||||
vk::raii::DeviceMemory vkMemory;
|
||||
|
||||
ImportedBuffer(span<u8> data, vk::raii::Buffer vkBuffer, vk::raii::DeviceMemory vkMemory)
|
||||
: vkBuffer{std::move(vkBuffer)},
|
||||
vkMemory{std::move(vkMemory)},
|
||||
span{data} {}
|
||||
|
||||
ImportedBuffer(const ImportedBuffer &) = delete;
|
||||
|
||||
ImportedBuffer(ImportedBuffer &&other)
|
||||
: vkBuffer{std::move(other.vkBuffer)},
|
||||
vkMemory{std::move(other.vkMemory)},
|
||||
span{other} {}
|
||||
|
||||
ImportedBuffer &operator=(const ImportedBuffer &) = delete;
|
||||
|
||||
ImportedBuffer &operator=(ImportedBuffer &&) = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A Vulkan image which VMA allocates and manages the backing memory for
|
||||
* @note Any images created with VMA_ALLOCATION_CREATE_MAPPED_BIT must not be utilized with this since it'll unconditionally unmap when a pointer is present which is illegal when an image was created with that flag as unmapping will be automatically performed on image deletion
|
||||
@ -94,11 +118,11 @@ namespace skyline::gpu::memory {
|
||||
*/
|
||||
class MemoryManager {
|
||||
private:
|
||||
const GPU &gpu;
|
||||
GPU &gpu;
|
||||
VmaAllocator vmaAllocator{VK_NULL_HANDLE};
|
||||
|
||||
public:
|
||||
MemoryManager(const GPU &gpu);
|
||||
MemoryManager(GPU &gpu);
|
||||
|
||||
~MemoryManager();
|
||||
|
||||
@ -121,5 +145,10 @@ namespace skyline::gpu::memory {
|
||||
* @brief Creates an image which is allocated and deallocated using RAII and is optimal for being mapped on the CPU
|
||||
*/
|
||||
Image AllocateMappedImage(const vk::ImageCreateInfo &createInfo);
|
||||
|
||||
/**
|
||||
* @brief Maps the input CPU mapped region into a new buffer
|
||||
*/
|
||||
ImportedBuffer ImportBuffer(span<u8> cpuMapping);
|
||||
};
|
||||
}
|
||||
|
@ -204,6 +204,12 @@ namespace skyline::gpu {
|
||||
bcnSupport[4] = isFormatSupported(vk::Format::eBc5UnormBlock) && isFormatSupported(vk::Format::eBc5SnormBlock);
|
||||
bcnSupport[5] = isFormatSupported(vk::Format::eBc6HSfloatBlock) && isFormatSupported(vk::Format::eBc6HUfloatBlock);
|
||||
bcnSupport[6] = isFormatSupported(vk::Format::eBc7UnormBlock) && isFormatSupported(vk::Format::eBc7SrgbBlock);
|
||||
|
||||
auto memoryProps{physicalDevice.getMemoryProperties2()};
|
||||
constexpr auto ReqMemFlags{vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostCached};
|
||||
for (u32 i{}; i < memoryProps.memoryProperties.memoryTypeCount; i++)
|
||||
if ((memoryProps.memoryProperties.memoryTypes[i].propertyFlags & ReqMemFlags) == ReqMemFlags)
|
||||
hostVisibleCoherentCachedMemoryType = i;
|
||||
}
|
||||
|
||||
std::string TraitManager::Summary() {
|
||||
@ -269,7 +275,7 @@ namespace skyline::gpu {
|
||||
);
|
||||
}
|
||||
|
||||
void TraitManager::ApplyDriverPatches(const vk::raii::Context &context) {
|
||||
void TraitManager::ApplyDriverPatches(const vk::raii::Context &context, adrenotools_gpu_mapping *mapping) {
|
||||
// Create an instance without validation layers in order to get pointers to the functions we need to patch from the driver
|
||||
vk::ApplicationInfo applicationInfo{
|
||||
.apiVersion = VK_API_VERSION_1_0,
|
||||
@ -294,5 +300,10 @@ namespace skyline::gpu {
|
||||
Logger::Info("BCeNabler skipped, blob BCN support is present");
|
||||
bcnSupport.set();
|
||||
}
|
||||
|
||||
if (adrenotools_validate_gpu_mapping(mapping)) {
|
||||
Logger::Info("Applied GPU memory import patch");
|
||||
supportsAdrenoDirectMemoryImport = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan_raii.hpp>
|
||||
#include <adrenotools/driver.h>
|
||||
#include <common.h>
|
||||
|
||||
namespace skyline::gpu {
|
||||
@ -49,8 +50,10 @@ namespace skyline::gpu {
|
||||
bool supportsExtendedDynamicState{}; //!< If the device supports the 'VK_EXT_extended_dynamic_state' Vulkan extension
|
||||
bool supportsNullDescriptor{}; //!< If the device supports the null descriptor feature in the 'VK_EXT_robustness2' Vulkan extension
|
||||
u32 subgroupSize{}; //!< Size of a subgroup on the host GPU
|
||||
u32 hostVisibleCoherentCachedMemoryType{std::numeric_limits<u32>::max()};
|
||||
|
||||
std::bitset<7> bcnSupport{}; //!< Bitmask of BCn texture formats supported, it is ordered as BC1, BC2, BC3, BC4, BC5, BC6H and BC7
|
||||
bool supportsAdrenoDirectMemoryImport{};
|
||||
|
||||
/**
|
||||
* @brief Manages a list of any vendor/device-specific errata in the host GPU
|
||||
@ -111,7 +114,7 @@ namespace skyline::gpu {
|
||||
/**
|
||||
* @brief Applies driver specific binary patches to the driver (e.g. BCeNabler)
|
||||
*/
|
||||
void ApplyDriverPatches(const vk::raii::Context &context);
|
||||
void ApplyDriverPatches(const vk::raii::Context &context, adrenotools_gpu_mapping *mapping);
|
||||
|
||||
/**
|
||||
* @return A summary of all the GPU traits as a human-readable string
|
||||
|
Reference in New Issue
Block a user