Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: apple support #89

Draft
wants to merge 26 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# apple
.DS_Store

# cmake
CMakeFiles/
.cmake/
Expand Down
23 changes: 23 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ option (NRI_ENABLE_NVTX_SUPPORT "Annotations for NVIDIA Nsight Systems" OFF)

# Options: backends
option (NRI_ENABLE_NONE_SUPPORT "Enable NONE backend" ON)
option (NRI_ENABLE_VK_SUPPORT "Enable VULKAN backend" ON)
option (NRI_ENABLE_METAL_SUPPORT "Enable METAL backend" ON)
option (NRI_ENABLE_D3D11_SUPPORT "Enable D3D11 backend" ON)
option (NRI_ENABLE_D3D12_SUPPORT "Enable D3D12 backend" ON)
option (NRI_ENABLE_VK_SUPPORT "Enable VULKAN backend" ON)
Expand Down Expand Up @@ -233,6 +235,24 @@ if (WIN32 AND NRI_ENABLE_D3D12_SUPPORT)
endif ()
endif ()

# METAL
if (NRI_ENABLE_METAL_SUPPORT AND APPLE)
message ("NRI adding backend: METAL")
set (COMPILE_DEFINITIONS ${COMPILE_DEFINITIONS} NRI_USE_MTL=1)
file (GLOB MTL_SOURCE "Source/Metal/*.cpp" "Source/Metal/*.mm" "Source/Metal/*.h" "Source/Metal/*.hpp" )
source_group ("" FILES ${MTL_SOURCE})
add_library (NRI_MTL STATIC ${MTL_SOURCE})
target_link_libraries(NRI_MTL
"-framework Metal"
"-framework MetalKit"
"-framework AppKit"
"-framework Foundation"
"-framework QuartzCore"
)
target_include_directories (NRI_MTL PRIVATE "Include" "Source/Shared" "External")
target_compile_definitions (NRI_MTL PRIVATE ${COMPILE_DEFINITIONS})
endif()

# VK
if (NRI_ENABLE_VK_SUPPORT)
message ("NRI adding backend: VK")
Expand Down Expand Up @@ -342,6 +362,9 @@ endif ()
if (NRI_ENABLE_VK_SUPPORT)
target_link_libraries (${PROJECT_NAME} PRIVATE NRI_VK)
endif ()
if (NRI_ENABLE_METAL_SUPPORT)
target_link_libraries (${PROJECT_NAME} PRIVATE NRI_MTL)
endif ()

set_property (TARGET ${PROJECT_NAME} PROPERTY FOLDER ${PROJECT_FOLDER})

Expand Down
52 changes: 52 additions & 0 deletions Include/Extensions/NRIWrapperMTL.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// © 2021 NVIDIA Corporation

#pragma once

#include "NRIMacro.h"
#include "NRIDeviceCreation.h"


NriNamespaceBegin


typedef void* MTLHeap;
typedef void* MTLDeviceHandle; // id<MTLDevice>
typedef void* MTLBufferHandle; // id<MTLHeap>
typedef void* MTLTextureHandle;

NriStruct(DeviceCreationMTLDesc)
{
bool enableNRIValidation;
MTLDeviceHandle MtlDevice;
};

NriStruct(CommandBufferMTLDesc)
{

};

NriStruct(BufferMTLDesc)
{
MTLBufferHandle buffer;
void* mappedMemory;
//MTLResourceOptions options;
};

NriStruct(TextureMTLDesc)
{
//MTLTextureHandle mtlTexture;
//MTLTextureDescriptor* descriptor;
};

NriStruct(MemoryMTLDesc)
{
uint64_t size;
// MTLStorageMode storage;

//MTLResourceOptions options;
};

NRI_API Nri(Result) NRI_CALL nriCreateDeviceFromMtlDevice(const NriRef(DeviceCreationMTLDesc) deviceDesc, NriRef(Device*) device);

NriNamespaceEnd

19 changes: 15 additions & 4 deletions Include/NRIDescs.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// © 2021 NVIDIA Corporation
// © 2021 NVIDIA Corporation

#pragma once

Expand Down Expand Up @@ -76,7 +76,8 @@ NriEnum(GraphicsAPI, uint8_t,
NONE, // Supports everything, does nothing, returns dummy non-NULL objects and ~0-filled descs, available if "NRI_ENABLE_NONE_SUPPORT = ON" in CMake
D3D11, // Direct3D 11 (feature set 11.1), available if "NRI_ENABLE_D3D11_SUPPORT = ON" in CMake
D3D12, // Direct3D 12 (feature set 11.1+), available if "NRI_ENABLE_D3D12_SUPPORT = ON" in CMake
VK // Vulkan 1.3 or 1.2+ (can be used on MacOS via MoltenVK), available if "NRI_ENABLE_VK_SUPPORT = ON" in CMake
VK, // Vulkan 1.3 or 1.2+ (can be used on MacOS via MoltenVK), available if "NRI_ENABLE_VK_SUPPORT = ON" in CMake
MTL
);

NriEnum(Result, uint8_t,
Expand Down Expand Up @@ -685,9 +686,14 @@ NriStruct(VertexAttributeVK) {
uint32_t location;
};

NriStruct(VertexAttributeMTL) {
uint32_t location;
};

NriStruct(VertexAttributeDesc) {
Nri(VertexAttributeD3D) d3d;
Nri(VertexAttributeVK) vk;
Nri(VertexAttributeMTL) mtl;
uint32_t offset;
Nri(Format) format;
uint16_t streamIndex;
Expand Down Expand Up @@ -1284,12 +1290,17 @@ NriStruct(PipelineStatisticsDesc) {
#pragma region [ Device desc ]
//============================================================================================================================================================================================

// defined in apple framework
#undef INTEL
#undef AMD

Comment on lines +1293 to +1295
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like these are #defined in apple framework.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind to add these undefs to the interface.

NriEnum(Vendor, uint8_t,
UNKNOWN,
NVIDIA,
AMD,
INTEL
);
INTEL,
APPLE
);

NriStruct(AdapterDesc) {
char name[256];
Expand Down
36 changes: 36 additions & 0 deletions Source/Creation/Creation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ Result CreateDeviceD3D12(const DeviceCreationDesc& deviceCreationDesc, DeviceBas
Result CreateDeviceD3D12(const DeviceCreationD3D12Desc& deviceCreationDesc, DeviceBase*& device);
#endif

#if NRI_USE_MTL
Result CreateDeviceMTL(const DeviceCreationDesc& deviceCreationDesc, DeviceBase*& device);
Result CreateDeviceMTL(const DeviceCreationMTLDesc& deviceCreationDesc, DeviceBase*& device);
#endif

#if NRI_USE_VK
Result CreateDeviceVK(const DeviceCreationDesc& deviceCreationDesc, DeviceBase*& device);
Result CreateDeviceVK(const DeviceCreationVKDesc& deviceDesc, DeviceBase*& device);
Expand Down Expand Up @@ -284,6 +289,24 @@ NRI_API Result NRI_CALL nriCreateDeviceFromD3D12Device(const DeviceCreationD3D12
return FinalizeDeviceCreation(deviceCreationDesc, *deviceImpl, device);
}

NRI_API Result NRI_CALL nriCreateDeviceFromMtlDevice(const DeviceCreationMTLDesc& deviceCreationMtlDesc, Device*& device) {
DeviceCreationDesc deviceCreationDesc = {};
deviceCreationDesc.graphicsAPI = GraphicsAPI::MTL;
deviceCreationDesc.enableNRIValidation = deviceCreationMtlDesc.enableNRIValidation;

Result result = Result::UNSUPPORTED;
DeviceBase* deviceImpl = nullptr;

#if NRI_USE_MTL
//result = CreateDeviceD3D12(tempDeviceCreationD3D12Desc, deviceImpl);
#endif

if (result != Result::SUCCESS)
return result;

return FinalizeDeviceCreation(deviceCreationDesc, *deviceImpl, device);
}

NRI_API Result NRI_CALL nriCreateDeviceFromVkDevice(const DeviceCreationVKDesc& deviceCreationVKDesc, Device*& device) {
DeviceCreationDesc deviceCreationDesc = {};
deviceCreationDesc.callbackInterface = deviceCreationVKDesc.callbackInterface;
Expand Down Expand Up @@ -325,6 +348,17 @@ NRI_API Format NRI_CALL nriConvertDXGIFormatToNRI(uint32_t dxgiFormat) {
return DXGIFormatToNRIFormat(dxgiFormat);
}

NRI_API uint32_t NRI_CALL nriConvertNRIFormatToMTL(Format format) {
MaybeUnused(format);

#if NRI_USE_VK
return NRIFormatToMTLFormat(format);
#else
return 0;
#endif
}


NRI_API uint32_t NRI_CALL nriConvertNRIFormatToVK(Format format) {
MaybeUnused(format);

Expand Down Expand Up @@ -443,6 +477,8 @@ NRI_API void NRI_CALL nriReportLiveObjects() {
pDebug->ReportLiveObjects(DXGI_DEBUG_ALL, (DXGI_DEBUG_RLO_FLAGS)((uint32_t)DXGI_DEBUG_RLO_DETAIL | (uint32_t)DXGI_DEBUG_RLO_IGNORE_INTERNAL));
}

#elif __APPLE__

#else
# include <vulkan/vulkan.h>
# define GET_VK_FUNCTION(instance, name) \
Expand Down
58 changes: 58 additions & 0 deletions Source/Metal/BufferMTL.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// © 2021 NVIDIA Corporation
#pragma once

#import <MetalKit/MetalKit.h>

namespace nri {

struct DeviceMTL;
struct MemoryMTL;

struct BufferMTL {

inline BufferMTL(DeviceMTL& device)
: m_Device(device) {
}

~BufferMTL();

inline id<MTLBuffer> GetHandle() const {
return m_Handle;
}

inline DeviceMTL& GetDevice() const {
return m_Device;
}

inline const BufferDesc& GetDesc() const {
return m_Desc;
}

void* Map(uint64_t offset, uint64_t size);
void Unmap();

void FinishMemoryBinding(MemoryMTL& memory, uint64_t memoryOffset);
Result Create(const BufferDesc& bufferDesc);

//================================================================================================================
// NRI
//================================================================================================================

void SetDebugName(const char* name);

private:
void UpdateLabel();

NSString* m_Label = nullptr;
DeviceMTL& m_Device;
id<MTLBuffer> m_Handle;
uint8_t* m_MappedMemory = nullptr;
uint64_t m_MappedMemoryOffset = 0;
uint64_t m_MappedMemoryRangeSize = 0;
uint64_t m_MappedMemoryRangeOffset = 0;
BufferDesc m_Desc = {};
bool m_OwnsNativeObjects = true;
};


};
44 changes: 44 additions & 0 deletions Source/Metal/BufferMTL.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "SharedMTL.h"

#include "BufferMTL.h"
#include "MemoryMTL.h"

using namespace nri;

void* BufferMTL::Map(uint64_t offset, uint64_t size) {
return (uint8_t*)[m_Handle contents] + offset;
}

BufferMTL::~BufferMTL() {
[m_Label release];
}

void BufferMTL::Unmap() {

}

void BufferMTL::FinishMemoryBinding(MemoryMTL& memory, uint64_t memoryOffset) {
m_Handle = [memory.GetHandle()
newBufferWithLength: m_Desc.size
options: MTLResourceCPUCacheModeDefaultCache
offset: memoryOffset];
UpdateLabel();
}

void BufferMTL::UpdateLabel() {
if(m_Handle && m_Label) {
[m_Handle setLabel: m_Label];
}
}



Result BufferMTL::Create(const BufferDesc& bufferDesc) {
m_Desc = bufferDesc;
}

void BufferMTL::SetDebugName(const char* name) {
m_Label = [NSString stringWithUTF8String:name];
[m_Label retain];
UpdateLabel();
}
38 changes: 38 additions & 0 deletions Source/Metal/CommandAllocatorMTL.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// © 2021 NVIDIA Corporation

#pragma once

namespace nri {

struct DeviceMTL;
struct CommandQueueMTL;

struct CommandAllocatorMTL {
inline CommandAllocatorMTL(DeviceMTL& device)
: m_Device(device) {
}

inline DeviceMTL& GetDevice() const {
return m_Device;
}

~CommandAllocatorMTL();


Result Create(const CommandQueue& commandQueue);

//================================================================================================================
// NRI
//================================================================================================================

void SetDebugName(const char* name);
Result CreateCommandBuffer(CommandBuffer*& commandBuffer);
void Reset();

private:
DeviceMTL& m_Device;
const struct CommandQueueMTL* m_CommandQueue;
};

}

19 changes: 19 additions & 0 deletions Source/Metal/CommandAllocatorMTL.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// © 2021 NVIDIA Corporation

#pragma region[ Core ]

static void NRI_CALL SetCommandAllocatorDebugName(CommandAllocator& commandAllocator, const char* name) {
//((CommandAllocatorVK&)commandAllocator).SetDebugName(name);
}

static Result NRI_CALL CreateCommandBuffer(CommandAllocator& commandAllocator, CommandBuffer*& commandBuffer) {
return ((CommandAllocatorMTL&)commandAllocator).CreateCommandBuffer(commandBuffer);
}

static void NRI_CALL ResetCommandAllocator(CommandAllocator& commandAllocator) {
//((CommandAllocatorVK&)commandAllocator).Reset();
}

#pragma endregion


Loading
Loading