metal sync extension
This commit is contained in:
@@ -11,7 +11,9 @@ file(GLOB_RECURSE LOADER_FILES CONFIGURE_DEPENDS
|
|||||||
add_library(GryphnMetalImpl STATIC ${SOURCE_FILES} ${LOADER_FILES})
|
add_library(GryphnMetalImpl STATIC ${SOURCE_FILES} ${LOADER_FILES})
|
||||||
target_include_directories(GryphnMetalImpl PUBLIC
|
target_include_directories(GryphnMetalImpl PUBLIC
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../core/src/
|
${CMAKE_CURRENT_SOURCE_DIR}/../../core/src/
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../core/
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../utils/
|
${CMAKE_CURRENT_SOURCE_DIR}/../../utils/
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../extensions/
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../
|
${CMAKE_CURRENT_SOURCE_DIR}/../../
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../platform/
|
${CMAKE_CURRENT_SOURCE_DIR}/../../platform/
|
||||||
|
@@ -35,9 +35,6 @@ gnDeviceFunctions loadMetalDeviceFunctions() {
|
|||||||
._gnCreateCommandPool = createMetalCommandPool,
|
._gnCreateCommandPool = createMetalCommandPool,
|
||||||
._gnDestroyCommandPool = destroyMetalCommandPool,
|
._gnDestroyCommandPool = destroyMetalCommandPool,
|
||||||
|
|
||||||
._gnCreateSemaphore = createMetalSemaphore,
|
|
||||||
._gnDestroySemaphore = destroyMetalSemaphore,
|
|
||||||
|
|
||||||
._gnCreateBuffer = createMetalBuffer,
|
._gnCreateBuffer = createMetalBuffer,
|
||||||
._gnBufferData = metalBufferData,
|
._gnBufferData = metalBufferData,
|
||||||
._gnMapBuffer = mapMetalBuffer,
|
._gnMapBuffer = mapMetalBuffer,
|
||||||
@@ -55,11 +52,6 @@ gnDeviceFunctions loadMetalDeviceFunctions() {
|
|||||||
._gnTextureData = metalTextureData,
|
._gnTextureData = metalTextureData,
|
||||||
._gnDestroyTexture = metalDestroyTexture,
|
._gnDestroyTexture = metalDestroyTexture,
|
||||||
|
|
||||||
._gnCreateFence = createMetalFence,
|
|
||||||
._gnWaitForFence = waitForMetalFence,
|
|
||||||
._gnResetFence = resetMetalFence,
|
|
||||||
._gnDestroyFence = destroyMetalFence,
|
|
||||||
|
|
||||||
._gnSubmit = metalSubmit,
|
._gnSubmit = metalSubmit,
|
||||||
._gnPresent = metalPresent,
|
._gnPresent = metalPresent,
|
||||||
|
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
#include "loader/src/gryphn_instance_functions.h"
|
#include "loader/src/gryphn_instance_functions.h"
|
||||||
#include "loader/src/gryphn_device_functions.h"
|
#include "loader/src/gryphn_device_functions.h"
|
||||||
#include "loader/src/gryphn_command_functions.h"
|
#include "loader/src/gryphn_command_functions.h"
|
||||||
|
#include "extensions/synchronization/loader/sync_functions.h"
|
||||||
|
|
||||||
gnInstanceFunctions loadMetalInstanceFunctions();
|
gnInstanceFunctions loadMetalInstanceFunctions();
|
||||||
gnDeviceFunctions loadMetalDeviceFunctions();
|
gnDeviceFunctions loadMetalDeviceFunctions();
|
||||||
gnCommandFunctions loadMetalCommandFunctions();
|
gnCommandFunctions loadMetalCommandFunctions();
|
||||||
|
gnSyncExtFunctions loadMetalSyncFunctions();
|
||||||
|
23
projects/apis/metal/loader/metal_sync_loader.m
Normal file
23
projects/apis/metal/loader/metal_sync_loader.m
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#include "metal_loader.h"
|
||||||
|
#include <sync/semaphore/metal_semaphore.h>
|
||||||
|
#include <sync/fence/metal_fence.h>
|
||||||
|
#include "presentation_queue/metal_presentation_queue.h"
|
||||||
|
#include "submit/metal_submit.h"
|
||||||
|
#include "present/metal_present.h"
|
||||||
|
|
||||||
|
gnSyncExtFunctions loadMetalSyncFunctions() {
|
||||||
|
return (gnSyncExtFunctions){
|
||||||
|
._gnPresentationQueueGetImageAsync = getMetalPresentQueueImageAsync,
|
||||||
|
|
||||||
|
._gnCreateSemaphore = createMetalSemaphore,
|
||||||
|
._gnDestroySemaphore = destroyMetalSemaphore,
|
||||||
|
|
||||||
|
._gnCreateFence = createMetalFence,
|
||||||
|
._gnWaitForFence = waitForMetalFence,
|
||||||
|
._gnResetFence = resetMetalFence,
|
||||||
|
._gnDestroyFence = destroyMetalFence,
|
||||||
|
|
||||||
|
._gnSubmitSync = metalSyncSubmit,
|
||||||
|
._gnPresentSync = metalPresentSync
|
||||||
|
};
|
||||||
|
}
|
@@ -30,12 +30,13 @@ gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCou
|
|||||||
.queueType = GN_QUEUE_GRAPHICS | GN_QUEUE_COMPUTE | GN_QUEUE_TRANSFER
|
.queueType = GN_QUEUE_GRAPHICS | GN_QUEUE_COMPUTE | GN_QUEUE_TRANSFER
|
||||||
};
|
};
|
||||||
|
|
||||||
if ([device supportsTextureSampleCount:1]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_1; }
|
if ([device supportsTextureSampleCount:1]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_1; }
|
||||||
if ([device supportsTextureSampleCount:2]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_2; }
|
if ([device supportsTextureSampleCount:2]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_2; }
|
||||||
if ([device supportsTextureSampleCount:4]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_4; }
|
if ([device supportsTextureSampleCount:4]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_4; }
|
||||||
if ([device supportsTextureSampleCount:8]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_8; }
|
if ([device supportsTextureSampleCount:8]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_8; }
|
||||||
if ([device supportsTextureSampleCount:16]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_16; }
|
if ([device supportsTextureSampleCount:16]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_16; }
|
||||||
if ([device supportsTextureSampleCount:32]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_32; }
|
if ([device supportsTextureSampleCount:32]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_32; }
|
||||||
|
devicesList[i].features.maxDepthSamples = devicesList[i].features.maxColorSamples;
|
||||||
|
|
||||||
devicesList[i].features.maxMemoryAllocations = 0x40000000;
|
devicesList[i].features.maxMemoryAllocations = 0x40000000;
|
||||||
devicesList[i].features.maxPushConstantSize = 4096;
|
devicesList[i].features.maxPushConstantSize = 4096;
|
||||||
|
@@ -8,4 +8,5 @@
|
|||||||
#include "texture/metal_texture.h"
|
#include "texture/metal_texture.h"
|
||||||
#import <QuartzCore/CAMetalLayer.h>
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
||||||
|
gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo info);
|
||||||
gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info);
|
gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info);
|
||||||
|
@@ -1,6 +1,53 @@
|
|||||||
#include "metal_present.h"
|
#include "metal_present.h"
|
||||||
|
#include <synchronization/commands/gryphn_sync_present.h>
|
||||||
|
|
||||||
gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) {
|
gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) {
|
||||||
|
|
||||||
|
for (int i =0 ; i < info.presentationQueueCount; i++) {
|
||||||
|
info.presentationQueues[i]->info.surface->windowSurface->layer.device = device->outputDevice->device;
|
||||||
|
id<CAMetalDrawable> drawable = [info.presentationQueues[i]->info.surface->windowSurface->layer nextDrawable];
|
||||||
|
if (drawable == nil) return GN_FAILED_TO_CREATE_FRAMEBUFFER;
|
||||||
|
|
||||||
|
__block gnPresentationQueue presentationQueue = info.presentationQueues[i];
|
||||||
|
__block uint32_t imageIndex = info.imageIndices[i];
|
||||||
|
|
||||||
|
id<MTLCommandBuffer> commandBuffer = [device->outputDevice->transferQueue commandBuffer];
|
||||||
|
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
|
||||||
|
uint32_tArrayListAdd(&presentationQueue->presentationQueue->avaliableTextures, imageIndex);
|
||||||
|
}];
|
||||||
|
|
||||||
|
id<MTLBlitCommandEncoder> blit = [commandBuffer blitCommandEncoder];
|
||||||
|
[blit copyFromTexture:info.presentationQueues[i]->images[info.imageIndices[i]]->texture->texture
|
||||||
|
sourceSlice:0
|
||||||
|
sourceLevel:0
|
||||||
|
sourceOrigin:(MTLOrigin){0, 0, 0}
|
||||||
|
sourceSize:(MTLSize){info.presentationQueues[i]->info.imageSize.x, info.presentationQueues[i]->info.imageSize.y, 1}
|
||||||
|
toTexture:drawable.texture
|
||||||
|
destinationSlice:0
|
||||||
|
destinationLevel:0
|
||||||
|
destinationOrigin:(MTLOrigin){0, 0, 0}];
|
||||||
|
|
||||||
|
[blit endEncoding];
|
||||||
|
|
||||||
|
[commandBuffer presentDrawable:drawable];
|
||||||
|
[commandBuffer commit];
|
||||||
|
device->outputDevice->executingCommandBuffer = commandBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
[device->outputDevice->executingCommandBuffer waitUntilScheduled];
|
||||||
|
|
||||||
|
for (int i = 0; i < info.presentationQueueCount; i++) {
|
||||||
|
if (info.presentationQueues[i]->info.imageSize.x != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.width ||
|
||||||
|
info.presentationQueues[i]->info.imageSize.y != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.height) {
|
||||||
|
return GN_SUBOPTIMAL_PRESENTATION_QUEUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo info) {
|
||||||
for (int i = 0; i < info.waitCount; i++) {
|
for (int i = 0; i < info.waitCount; i++) {
|
||||||
while (!info.waitSemaphores[i]->semaphore->eventTriggered) {}
|
while (!info.waitSemaphores[i]->semaphore->eventTriggered) {}
|
||||||
}
|
}
|
||||||
|
@@ -11,5 +11,6 @@ typedef struct gnPlatformPresentationQueue_t {
|
|||||||
} gnPlatformPresentationQueue;
|
} gnPlatformPresentationQueue;
|
||||||
|
|
||||||
gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo);
|
gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo);
|
||||||
gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex);
|
gnReturnCode getMetalPresentQueueImageAsync(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex);
|
||||||
|
gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint32_t* imageIndex);
|
||||||
void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue);
|
void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue);
|
||||||
|
@@ -48,7 +48,7 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation
|
|||||||
return GN_SUCCESS;
|
return GN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex) {
|
gnReturnCode getMetalPresentQueueImageAsync(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex) {
|
||||||
while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {}
|
while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {}
|
||||||
*imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0];
|
*imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0];
|
||||||
uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures);
|
uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures);
|
||||||
@@ -56,6 +56,13 @@ gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQue
|
|||||||
return GN_SUCCESS;
|
return GN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint32_t* imageIndex) {
|
||||||
|
while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {}
|
||||||
|
*imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0];
|
||||||
|
uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures);
|
||||||
|
return GN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue) {
|
void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue) {
|
||||||
free(presentationQueue->presentationQueue->avaliableTextures.data);
|
free(presentationQueue->presentationQueue->avaliableTextures.data);
|
||||||
presentationQueue->presentationQueue->avaliableTextures.count = 0;
|
presentationQueue->presentationQueue->avaliableTextures.count = 0;
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
#include "commands/command_buffer/metal_command_buffer.h"
|
#include "commands/command_buffer/metal_command_buffer.h"
|
||||||
#include "debugger/gryphn_debugger.h"
|
#include "debugger/gryphn_debugger.h"
|
||||||
#include "commands/command_pool/metal_command_pool.h"
|
#include "commands/command_pool/metal_command_pool.h"
|
||||||
#include "sync/fence/gryphn_fence.h"
|
#include "synchronization/commands/gryphn_sync_submit.h"
|
||||||
|
|
||||||
|
gnReturnCode metalSyncSubmit(gnOutputDevice device, gnSubmitSyncInfo info);
|
||||||
gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info);
|
gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info);
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#include "metal_submit.h"
|
#include "metal_submit.h"
|
||||||
|
#include "synchronization/fence/gryphn_fence.h"
|
||||||
|
|
||||||
gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info) {
|
gnReturnCode metalSyncSubmit(gnOutputDevice device, gnSubmitSyncInfo info) {
|
||||||
for (int i = 0; i < info.waitCount; i++) {
|
for (int i = 0; i < info.waitCount; i++) {
|
||||||
while (!info.waitSemaphores[i]->semaphore->eventTriggered) {}
|
while (!info.waitSemaphores[i]->semaphore->eventTriggered) {}
|
||||||
}
|
}
|
||||||
@@ -23,3 +24,13 @@ gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info) {
|
|||||||
|
|
||||||
return GN_SUCCESS;
|
return GN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info) {
|
||||||
|
for (int i = 0; i < info.commandBufferCount; i++) {
|
||||||
|
id<MTLCommandBuffer> commandBuffer = info.commandBuffers[i]->commandBuffer->commandBuffer;
|
||||||
|
[commandBuffer commit];
|
||||||
|
}
|
||||||
|
|
||||||
|
[info.commandBuffers[info.commandBufferCount - 1]->commandBuffer->commandBuffer waitUntilCompleted];
|
||||||
|
return GN_SUCCESS;
|
||||||
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "sync/fence/gryphn_fence.h"
|
#include "synchronization/fence/gryphn_fence.h"
|
||||||
#import <Metal/Metal.h>
|
#import <Metal/Metal.h>
|
||||||
#import <Metal/MTLEvent.h>
|
#import <Metal/MTLEvent.h>
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "sync/semaphore/gryphn_semaphore.h"
|
#include "synchronization/semaphore/gryphn_semaphore.h"
|
||||||
#import <Metal/MTLEvent.h>
|
#import <Metal/MTLEvent.h>
|
||||||
|
|
||||||
typedef struct gnPlatformSemaphore_t {
|
typedef struct gnPlatformSemaphore_t {
|
||||||
|
@@ -28,7 +28,7 @@ void checkDestroyOutputDevice(gnOutputDeviceHandle device) {
|
|||||||
|
|
||||||
#ifdef GN_PLATFORM_MACOS
|
#ifdef GN_PLATFORM_MACOS
|
||||||
gnReturnCode checkCreateSurfaceMacOS(gnWindowSurfaceHandle windowSurface, gnInstanceHandle instance, gnMacOSWindowSurfaceInfo createInfo) {
|
gnReturnCode checkCreateSurfaceMacOS(gnWindowSurfaceHandle windowSurface, gnInstanceHandle instance, gnMacOSWindowSurfaceInfo createInfo) {
|
||||||
CHECK_FUNCTION_WITH_RETURN_CODE(instance, _gnCreateMacOSWindowSurface, instanceFunctions, surface, instance, info);
|
CHECK_FUNCTION_WITH_RETURN_CODE(instance, _gnCreateMacOSWindowSurface, instanceFunctions, windowSurface, instance, createInfo);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef GN_PLATFORM_LINUX
|
#ifdef GN_PLATFORM_LINUX
|
||||||
|
Reference in New Issue
Block a user