Skip to content

Commit

Permalink
feat: add Creation logic
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Pollind <[email protected]>
  • Loading branch information
pollend committed Dec 30, 2024
1 parent ae69716 commit e757b6e
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 24 deletions.
83 changes: 83 additions & 0 deletions Source/Creation/Creation.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#import <MetalKit/MetalKit.h>

#include "SharedExternal.h"

using namespace nri;

// referenced from Molten VK
static uint32_t GetEntryProperty(io_registry_entry_t entry, CFStringRef propertyName) {

uint32_t value = 0;

CFTypeRef cfProp = IORegistryEntrySearchCFProperty(entry,
kIOServicePlane,
propertyName,
kCFAllocatorDefault,
kIORegistryIterateRecursively |
kIORegistryIterateParents);
if (cfProp) {
const uint32_t* pValue = reinterpret_cast<const uint32_t*>(CFDataGetBytePtr((CFDataRef)cfProp));
if (pValue) { value = *pValue; }
CFRelease(cfProp);
}

return value;
}


static int SortAdaptersByDedicatedVideoMemorySize(const void* pa, const void* pb) {
AdapterDesc* a = (AdapterDesc*)pa;
AdapterDesc* b = (AdapterDesc*)pb;

if (a->videoMemorySize > b->videoMemorySize)
return -1;

if (a->videoMemorySize < b->videoMemorySize)
return 1;

return 0;
}

NRI_API Result NRI_CALL nriEnumerateAdapters(AdapterDesc* adapterDescs, uint32_t& adapterDescNum) {

NSArray<id<MTLDevice>>* devices = MTLCopyAllDevices();
if(!adapterDescs) {
adapterDescNum = (uint32_t)devices.count;
return Result::SUCCESS;
}

AdapterDesc* adapterDescsSorted = (AdapterDesc*)alloca(sizeof(AdapterDesc) * devices.count);
for(size_t i = 0; i < devices.count; i++) {
NSString* name = [devices[i] name];
[name getCString:adapterDescsSorted[i].name maxLength: sizeof(adapterDescs[i].name) - 1 encoding: NSASCIIStringEncoding];
const uint64_t regID = [devices[i] registryID];
adapterDescsSorted[i].luid = regID;
if (regID)
{
io_registry_entry_t entry = IOServiceGetMatchingService(MACH_PORT_NULL, IORegistryEntryIDMatching(regID));
if (entry)
{
// That returned the IOGraphicsAccelerator nub. Its parent, then, is the actual PCI device.
io_registry_entry_t deviceEntry;
if (IORegistryEntryGetParentEntry(entry, kIOServicePlane, &deviceEntry) == kIOReturnSuccess)
{
adapterDescsSorted[i].vendor = GetVendorFromID(GetEntryProperty(deviceEntry, CFSTR("vendor-id"))) ;
adapterDescsSorted[i].deviceId = GetEntryProperty(deviceEntry, CFSTR("device-id"));
}
}
} else {
adapterDescsSorted[i].vendor = nri::Vendor::APPLE;
}
adapterDescsSorted[i].videoMemorySize = [devices[i] recommendedMaxWorkingSetSize];
NSProcessInfo *pinfo = [NSProcessInfo processInfo];
adapterDescsSorted[i].systemMemorySize = [pinfo physicalMemory];
}

// Sort by video memory size
qsort(adapterDescsSorted, devices.count, sizeof(adapterDescsSorted[0]), SortAdaptersByDedicatedVideoMemorySize);
for(size_t i = 0; i < MIN(devices.count, adapterDescNum); i++) {
adapterDescs[i] = adapterDescsSorted[i];
}
adapterDescNum = (uint32_t)MIN(devices.count, adapterDescNum);
return Result::SUCCESS;
}
2 changes: 1 addition & 1 deletion Source/Metal/CommandBufferMTL.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ struct CommandBufferMTL {
uint32_t m_dirtyVertexBufferBits = 0;
struct CmdVertexBuffer m_vertexBuffers[32];
struct ShadingRateDesc m_shadingRateDesc;
MTLViewport m_viewports[16];
MTLViewport m_Viewports[16];
MTLScissorRect m_Scissors[16];
Color32f m_BlendColor;
uint8_t m_StencilFront;
Expand Down
43 changes: 34 additions & 9 deletions Source/Metal/CommandBufferMTL.mm
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
[m_Annotations removeLastObject];
}
if(m_numViewports > 0)
[m_RendererEncoder setViewports: m_viewports count: m_numViewports];
[m_RendererEncoder setViewports: m_Viewports count: m_numViewports];
if(m_numScissors > 0)
[m_RendererEncoder setScissorRects: m_Scissors count: m_numScissors];
if(m_DirtyBits & CommandBufferDirtyBits::CMD_DIRTY_BLEND_CONSTANT)
Expand Down Expand Up @@ -245,6 +245,7 @@
m_renderPassDescriptor.colorAttachments[i].clearColor = MTLClearColorMake(0, 0, 0, 1);
m_renderPassDescriptor.colorAttachments[i].loadAction = MTLLoadActionLoad;
m_renderPassDescriptor.colorAttachments[i].storeAction = MTLStoreActionStore;

}

if(attachmentsDesc.depthStencil) {
Expand All @@ -264,17 +265,17 @@

void CommandBufferMTL::SetViewports(const Viewport* viewports, uint32_t viewportNum) {
for(size_t i = 0; i < viewportNum; i++) {
m_viewports[i].originX = viewports[i].x;
m_viewports[i].originY = viewports[i].y;
m_viewports[i].width = viewports[i].width;
m_viewports[i].height = viewports[i].height;
m_viewports[i].znear = viewports[i].depthMin;
m_viewports[i].zfar = viewports[i].depthMax;
m_Viewports[i].originX = viewports[i].x;
m_Viewports[i].originY = viewports[i].y;
m_Viewports[i].width = viewports[i].width;
m_Viewports[i].height = viewports[i].height;
m_Viewports[i].znear = viewports[i].depthMin;
m_Viewports[i].zfar = viewports[i].depthMax;
}
m_numViewports = viewportNum;
if(m_RendererEncoder && m_numViewports > 0)
[m_RendererEncoder
setViewports: m_viewports
setViewports: m_Viewports
count: m_numViewports];
}

Expand Down Expand Up @@ -325,11 +326,35 @@
void CommandBufferMTL::ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) {
MTLRenderPassDescriptor* renderPassDesc = [MTLRenderPassDescriptor alloc];
id<MTLRenderCommandEncoder> rendererEncoder = [m_Handle renderCommandEncoderWithDescriptor: renderPassDesc];


simd::float4 vertices[6 * 16];
// simd::float4 clearColors[kMVKClearAttachmentCount];

for(size_t i = 0; i < clearDescNum; i++) {

simd::float2 srcBL = simd_make_float2(rects[i].x / m_Viewports[i].width,
(m_Viewports[i].height - rects[i].y) / m_Viewports[i].height);
simd::float2 srcTR = simd_make_float2(rects[i].x / m_Viewports[i].width,
(m_Viewports[i].height - rects[i].y) / m_Viewports[i].height);
// simd::float2 dstBL = simd_make_float2((CGFloat)(do0.x) / (CGFloat)dstExtent.width,
// (CGFloat)(dstExtent.height - do1.y) / (CGFloat)dstExtent.height);
// simd::float2 dstTR = simd_make_float2((CGFloat)(do1.x) / (CGFloat)dstExtent.width,
// (CGFloat)(dstExtent.height - do0.y) / (CGFloat)dstExtent.height);


}

if(m_numViewports > 0)
[rendererEncoder
setViewports: m_Viewports
count: m_numViewports];
[rendererEncoder setCullMode: MTLCullModeNone];
[rendererEncoder setTriangleFillMode: MTLTriangleFillModeFill];
[rendererEncoder setDepthBias: 0 slopeScale: 0 clamp: 0];
[rendererEncoder setRenderPipelineState: m_Device.GetClearPipeline(clearDescs, clearDescNum)];


[rendererEncoder endEncoding];

}

Expand Down
10 changes: 9 additions & 1 deletion Source/Metal/DeviceMTL.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ struct DeviceMTL final : public DeviceBase {
return m_Desc;
}

id<MTLRenderPipelineState> GetClearPipeline(ClearDesc* desc, size_t numFormat);
id<MTLRenderPipelineState> GetClearPipeline(const ClearDesc* desc, size_t numFormat);

void Destruct() override;
Result FillFunctionTable(CoreInterface& table) const override;
Expand All @@ -68,6 +68,11 @@ struct DeviceMTL final : public DeviceBase {
Result BindTextureMemory(const TextureMemoryBindingDesc* memoryBindingDescs, uint32_t memoryBindingDescNum);

Result Create(const DeviceCreationDesc& deviceCreationDesc, const DeviceCreationMTLDesc& deviceCreationVKDesc, bool isWrapper);

struct ClearPipelineKey {


};
private:
//Lock m_Lock;
id<MTLDevice> m_Device;
Expand All @@ -77,5 +82,8 @@ struct DeviceMTL final : public DeviceBase {
MTLGPUFamily m_Family;
bool m_OwnsNativeObjects = true;
Lock m_Lock;

std::unordered_map<uint32_t,id<MTLRenderPipelineState>> m_clearPipelineState;

};
}; // namespace nri
49 changes: 37 additions & 12 deletions Source/Metal/DeviceMTL.mm
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ static uint32_t GetEntryProperty(io_registry_entry_t entry, CFStringRef property
}


id<MTLRenderPipelineState> DeviceMTL::GetClearPipeline(ClearDesc* desc, size_t numFormats) {

static id<MTLRenderPipelineState> CreateClearPipeline(id<MTLDevice> device, const ClearDesc* desc, size_t numFormats) {
NSString* clearVert = [NSString stringWithCString: "\
#include <metal_stdlib> \n\
using namespace metal; \n\
Expand All @@ -114,15 +113,15 @@ vertex VaryingsPos vertClear(AttributesPos attributes [[stage_in]], constant Cle

NSMutableString* clearFrag = [NSMutableString alloc];
[clearFrag appendString: @"\
#include <metal_stdlib> \n\
using namespace metal; \n\
typedef struct { \n\
float4 v_position [[position]]; \n\
} VaryingsPos; \n\
#include <metal_stdlib> \n\
using namespace metal; \n\
typedef struct { \n\
loat4 v_position [[position]]; \n\
} VaryingsPos; \n\
typedef struct { \n\
float4 colors[16]; \n\
} ClearColorsIn; \n\
typedef struct { \n\
} ClearColorsIn; \n\
typedef struct { \n\
"];
for(uint32_t i = 0; i < numFormats; i++) {
[clearFrag appendFormat: @"float4 color%u [[color(%u)]];", i, desc[i].colorAttachmentIndex];
Expand All @@ -138,8 +137,8 @@ fragment ClearColorsOut fragClear(VaryingsPos varyings [[stage_in]], constant Cl
return ccOut;\n\
}"];

id<MTLFunction> vtxFunc = initShaderFromSource(m_Device, clearVert, @"vertClear");
id<MTLFunction> fragFunc = initShaderFromSource(m_Device, clearFrag, @"fragClear");
id<MTLFunction> vtxFunc = initShaderFromSource(device, clearVert, @"vertClear");
id<MTLFunction> fragFunc = initShaderFromSource(device, clearFrag, @"fragClear");
MTLRenderPipelineDescriptor* renderPipelineDesc = [MTLRenderPipelineDescriptor new]; // temp retain
// owner->setMetalObjectLabel(plDesc, @"ClearRenderAttachments");
renderPipelineDesc.vertexFunction = vtxFunc;
Expand Down Expand Up @@ -169,7 +168,7 @@ fragment ClearColorsOut fragClear(VaryingsPos varyings [[stage_in]], constant Cl
vbDesc.stride = vtxStride;

NSError* error = nil;
id <MTLRenderPipelineState> rps = [m_Device newRenderPipelineStateWithDescriptor:renderPipelineDesc error: &error];
id <MTLRenderPipelineState> rps = [device newRenderPipelineStateWithDescriptor:renderPipelineDesc error: &error];

[vtxFunc release]; // temp release
[fragFunc release]; // temp release
Expand All @@ -178,6 +177,17 @@ fragment ClearColorsOut fragClear(VaryingsPos varyings [[stage_in]], constant Cl
return rps;
}

//TODO: implement this differently
id<MTLRenderPipelineState> DeviceMTL::GetClearPipeline(const ClearDesc* desc, size_t numFormats) {
uint32_t key = 0;
for(uint32_t i = 0; i < numFormats; i++) {
key |= (1 << desc[i].colorAttachmentIndex);
}
id<MTLRenderPipelineState> rps = CreateClearPipeline(m_Device, desc, numFormats);
m_clearPipelineState[key] = rps;
return rps;
}


void DeviceMTL::GetMemoryDesc(const BufferDesc& bufferDesc, MemoryLocation memoryLocation, MemoryDesc& memoryDesc) const {
MemoryTypeInfo memoryTypeInfo;
Expand Down Expand Up @@ -270,6 +280,21 @@ fragment ClearColorsOut fragClear(VaryingsPos varyings [[stage_in]], constant Cl
m_OwnsNativeObjects = !isWrapper;
if(isWrapper) {
m_Device = *(id<MTLDevice>*)&deviceCreationMTLDesc.MtlDevice;
} else {
NSArray<id<MTLDevice>>* devices = MTLCopyAllDevices();
uint32_t i = 0;
for(i = 0; i < devices.count; i++) {
if(deviceCreationDesc.adapterDesc) {
const uint64_t luid = [devices[i] registryID];
if(deviceCreationDesc.adapterDesc->luid == luid) {
m_Device = devices[i];
break;
}
} else {
break;
}
}
RETURN_ON_FAILURE(this, i != devices.count, Result::INVALID_ARGUMENT, "Can't create a device: physical device not found");
}

strncpy(m_Desc.adapterDesc.name, [m_Device.name UTF8String], sizeof(m_Desc.adapterDesc.name));
Expand Down
1 change: 0 additions & 1 deletion Source/Metal/ImplMTL.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ Result CreateDeviceMTL(const DeviceCreationDesc& desc, DeviceBase*& device) {
StdAllocator<uint8_t> allocator(desc.allocationCallbacks);
DeviceMTL* impl = Allocate<DeviceMTL>(allocator, desc.callbackInterface, allocator);
Result result = impl->Create(desc, {}, false);


MTLPurgeableState a;
MTLStorageMode mode;
Expand Down

0 comments on commit e757b6e

Please sign in to comment.