metal queue submission
This commit is contained in:
@@ -21,4 +21,11 @@ gnReturnCode gnCreateGLFWWindowSurface(struct gnWindowSurface_t* windowSurface,
|
||||
return gnCreateMacOSWindowSurface(windowSurface, instance, surfaceCreateInfo);
|
||||
}
|
||||
|
||||
// gnReturnCode gnCreateGLFWWindowSurface(struct gnWindowSurface_t* windowSurface, struct gnInstance_t* instance, GLFWwindow* window) {
|
||||
// gnMetalWindowSurfaceInfo surfaceCreateInfo = {
|
||||
// .layer = (CAMetalLayer*)glfwGetCocoaWindow(window).contentView.layer;
|
||||
// };
|
||||
// return gnCreateMetalWindowSurface(windowSurface, instance, surfaceCreateInfo);
|
||||
// }
|
||||
|
||||
#endif
|
||||
|
@@ -5,17 +5,20 @@
|
||||
gnReturnCode gnCommandPoolAllocateCommandBuffersFn(struct gnCommandBuffer_t* commandBuffers, uint32_t count, struct gnCommandPool_t* pool) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
commandBuffers[i].commandBuffer = malloc(sizeof(gnPlatformCommandBuffer));
|
||||
commandBuffers[i].commandBuffer->commandBuffer = [pool->commandPool->commandQueue commandBuffer];
|
||||
}
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
||||
gnReturnCode gnBeginCommandBuffer(struct gnCommandBuffer_t* commandBuffer) {
|
||||
void gnResetCommandBufferFn(struct gnCommandBuffer_t *commandBuffer) {
|
||||
// do nothing
|
||||
}
|
||||
gnReturnCode gnBeginCommandBufferFn(struct gnCommandBuffer_t* commandBuffer) {
|
||||
commandBuffer->commandBuffer->boundGraphcisPipeline = NULL;
|
||||
commandBuffer->commandBuffer->commandBuffer = [commandBuffer->commandPool->commandPool->commandQueue commandBuffer];
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
||||
gnReturnCode gnEndCommandBuffer(struct gnCommandBuffer_t* commandBuffer) {
|
||||
gnReturnCode gnEndCommandBufferFn(struct gnCommandBuffer_t* commandBuffer) {
|
||||
// [commandBuffer->commandBuffer->commandBuffer commit];
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
@@ -8,19 +8,19 @@
|
||||
gnReturnCode gnCreateOutputDeviceFn(gnOutputDevice* outputDevice, gnInstance* instance, struct gnOutputDeviceInfo_t deviceInfo) {
|
||||
outputDevice->outputDevice = malloc(sizeof(gnPlatformOutputDevice));
|
||||
outputDevice->outputDevice->device = deviceInfo.physicalDevice.physicalDevice->device.retain;
|
||||
// outputDevice->outputDevice->queueCount = deviceInfo.queueInfoCount;
|
||||
// outputDevice->outputDevice->queues = malloc(sizeof(id<MTLCommandQueue>) * deviceInfo.queueInfoCount);
|
||||
// for (int i = 0; i < deviceInfo.queueInfoCount; i++) {
|
||||
// outputDevice->outputDevice->queues[i] = outputDevice->outputDevice->device.newCommandQueue;
|
||||
// }
|
||||
outputDevice->outputDevice->queueCount = deviceInfo.queueInfoCount;
|
||||
outputDevice->outputDevice->queues = malloc(sizeof(id<MTLCommandQueue>) * deviceInfo.queueInfoCount);
|
||||
for (int i = 0; i < deviceInfo.queueInfoCount; i++) {
|
||||
outputDevice->outputDevice->queues[i] = outputDevice->outputDevice->device.newCommandQueue;
|
||||
}
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
||||
void gnDestroyOutputDeviceFn(gnOutputDevice* device) {
|
||||
// for (int i = 0; i < device->outputDevice->queueCount; i++) {
|
||||
// [device->outputDevice->queues[i] release];
|
||||
// }
|
||||
for (int i = 0; i < device->outputDevice->queueCount; i++) {
|
||||
[device->outputDevice->queues[i] release];
|
||||
}
|
||||
[device->outputDevice->device release];
|
||||
free(device->outputDevice);
|
||||
}
|
||||
|
33
rendering_api/metal/src/core/present/metal_present.m
Normal file
33
rendering_api/metal/src/core/present/metal_present.m
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "core/present/gryphn_present.h"
|
||||
#include "core/instance/metal_instance.h"
|
||||
#include "core/surface/metal_surface.h"
|
||||
#include "core/devices/metal_output_devices.h"
|
||||
#include "core/sync/semaphore/metal_semaphore.h"
|
||||
#include "core/presentation_queue/metal_presentation_queue.h"
|
||||
#include "core/debugger/gryphn_debugger.h"
|
||||
#import <QuartzCore/CAMetalLayer.h>
|
||||
|
||||
gnReturnCode gnPresentFn(struct gnOutputDevice_t* device, struct gnPresentInfo_t info) {
|
||||
for (int i = 0; i < info.waitCount; i++) {
|
||||
while (!info.waitSemaphores[i].semaphore->eventTriggered) {}
|
||||
}
|
||||
|
||||
info.presentationQueues->info.surface.windowSurface->layer.device = device->outputDevice->device;
|
||||
id<CAMetalDrawable> drawable = [info.presentationQueues->info.surface.windowSurface->layer nextDrawable];
|
||||
|
||||
id<MTLCommandBuffer> commandBuffer = [device->outputDevice->queues[info.queueIndex] commandBuffer];
|
||||
|
||||
MTLRenderPassDescriptor* passDesc = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||
passDesc.colorAttachments[0].texture = drawable.texture;
|
||||
passDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||
passDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||
passDesc.colorAttachments[0].clearColor = MTLClearColorMake(1.0f, 0, 0, 1.0f);
|
||||
id<MTLRenderCommandEncoder> render = [commandBuffer renderCommandEncoderWithDescriptor:passDesc];
|
||||
[render endEncoding];
|
||||
|
||||
[commandBuffer presentDrawable:drawable];
|
||||
[commandBuffer commit];
|
||||
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
@@ -5,4 +5,6 @@
|
||||
typedef struct gnPlatformPresentationQueue_t {
|
||||
int textureCount;
|
||||
id<MTLTexture>* textures;
|
||||
|
||||
uint32_t currentImage;
|
||||
} gnPlatformPresentationQueue;
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include "core/devices/metal_output_devices.h"
|
||||
#include "core/debugger/gryphn_debugger.h"
|
||||
#include "core/texture/metal_texture.h"
|
||||
#include "core/sync/semaphore/metal_semaphore.h"
|
||||
|
||||
gnReturnCode gnCreatePresentationQueueFn(gnPresentationQueue* presentationQueue, const gnOutputDevice* device, struct gnPresentationQueueInfo_t presentationInfo) {
|
||||
if (presentationInfo.minImageCount > 3) {
|
||||
@@ -45,6 +46,14 @@ gnReturnCode gnCreatePresentationQueueFn(gnPresentationQueue* presentationQueue,
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
||||
void gnPresentationQueueGetImageFn(gnPresentationQueue* presentationQueue, uint64_t timeout, struct gnSemaphore_t* semaphore, uint32_t* imageIndex) {
|
||||
semaphore->semaphore->eventTriggered = gnFalse;
|
||||
*imageIndex = presentationQueue->presentationQueue->currentImage;
|
||||
presentationQueue->presentationQueue->currentImage++;
|
||||
presentationQueue->presentationQueue->currentImage %= presentationQueue->imageCount;
|
||||
semaphore->semaphore->eventTriggered = gnTrue;
|
||||
}
|
||||
|
||||
void gnDestroyPresentationQueueFn(gnPresentationQueue *presentationQueue) {
|
||||
for (int i = 0; i < presentationQueue->imageCount; i++) {
|
||||
[presentationQueue->presentationQueue->textures[i] release];
|
||||
|
28
rendering_api/metal/src/core/submit/metal_submit.m
Normal file
28
rendering_api/metal/src/core/submit/metal_submit.m
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "core/submit/gryphn_submit.h"
|
||||
#include "core/sync/semaphore/metal_semaphore.h"
|
||||
#include "core/commands/command_buffer/metal_command_buffer.h"
|
||||
#include "core/debugger/gryphn_debugger.h"
|
||||
#include "core/commands/command_pool/metal_command_pool.h"
|
||||
|
||||
gnReturnCode gnSubmitFn(struct gnOutputDevice_t* device, struct gnSubmitInfo_t info) {
|
||||
for (int i = 0; i < info.waitCount; i++) {
|
||||
while (!info.waitSemaphores[i].semaphore->eventTriggered) {}
|
||||
}
|
||||
|
||||
|
||||
__block gnSemaphore* semsToSignal = info.signalSemaphores;
|
||||
__block int semsToSignalCount = info.signalCount;
|
||||
|
||||
for (int i = 0; i < info.commandBufferCount; i++) {
|
||||
id<MTLCommandBuffer> commandBuffer = info.commandBuffers[i].commandBuffer->commandBuffer;
|
||||
[info.commandBuffers[i].commandBuffer->commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
|
||||
for (int c = 0; c < semsToSignalCount; c++) {
|
||||
semsToSignal[c].semaphore->eventTriggered = gnTrue;
|
||||
}
|
||||
}];
|
||||
|
||||
[commandBuffer commit];
|
||||
}
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
@@ -3,6 +3,7 @@
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
typedef struct gnPlatformWindowSurface_t{
|
||||
CAMetalLayer* layer;
|
||||
} gnPlatformWindowSurface;
|
||||
|
||||
|
||||
|
@@ -15,11 +15,14 @@ gnReturnCode gnCreateMacOSWindowSurfaceFn(struct gnWindowSurface_t* windowSurfac
|
||||
CAMetalLayer* layer = [CAMetalLayer layer];
|
||||
[layer setContentsScale:[window backingScaleFactor]];
|
||||
[layer setFramebufferOnly:YES];
|
||||
[layer setPixelFormat:MTLPixelFormatBGRA8Unorm_sRGB];
|
||||
[layer setFrame:view.bounds];
|
||||
|
||||
[view setLayer:layer];
|
||||
[view setWantsLayer:YES];
|
||||
|
||||
windowSurface->windowSurface = malloc(sizeof(gnPlatformWindowSurface));
|
||||
windowSurface->windowSurface->layer = layer;
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -28,9 +31,6 @@ void gnDestroyWindowSurfaceFn(struct gnWindowSurface_t *windowSurface) {
|
||||
}
|
||||
|
||||
struct gnSurfaceDetails_t gnGetSurfaceDetailsFn(
|
||||
// struct gnWindowSurface_t* windowSurface,
|
||||
// struct gnPhysicalDevice_t device,
|
||||
// uint32_t* formatCount
|
||||
struct gnWindowSurface_t* windowSurface, struct gnPhysicalDevice_t device
|
||||
) {
|
||||
struct gnSurfaceDetails_t surfaceDetails;
|
||||
|
@@ -4,7 +4,5 @@
|
||||
#import <Metal/MTLEvent.h>
|
||||
|
||||
typedef struct gnPlatformFence_t {
|
||||
id<MTLSharedEvent> fence;
|
||||
MTLSharedEventListener* listener;
|
||||
dispatch_semaphore_t semaphore;
|
||||
|
||||
} gnPlatformFence;
|
||||
|
@@ -2,31 +2,32 @@
|
||||
#include "core/devices/metal_output_devices.h"
|
||||
|
||||
gnReturnCode gnCreateFenceFn(struct gnFence_t* fence, struct gnOutputDevice_t* device) {
|
||||
fence->fence = malloc(sizeof(gnPlatformFence));
|
||||
// fence->fence = malloc(sizeof(gnPlatformFence));
|
||||
|
||||
fence->fence->fence = [device->outputDevice->device newSharedEvent];
|
||||
fence->fence->listener = [[MTLSharedEventListener alloc] init];
|
||||
fence->fence->semaphore = dispatch_semaphore_create(1);
|
||||
// fence->fence->fence = [device->outputDevice->device newSharedEvent];
|
||||
// fence->fence->listener = [[MTLSharedEventListener alloc] init];
|
||||
// fence->fence->semaphore = dispatch_semaphore_create(1);
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
void gnSignalFenceFn(struct gnFence_t* fence) {
|
||||
dispatch_semaphore_signal(fence->fence->semaphore);
|
||||
// dispatch_semaphore_signal(fence->fence->semaphore);
|
||||
}
|
||||
void gnWaitForFenceFn(struct gnFence_t* fence, uint64_t timeout) {
|
||||
dispatch_semaphore_wait(fence->fence->semaphore, timeout);
|
||||
// dispatch_semaphore_wait(fence->fence->semaphore, timeout);
|
||||
while (fence->signaled == gnFalse) {}
|
||||
}
|
||||
void gnResetFenceFn(struct gnFence_t* fence) {
|
||||
dispatch_semaphore_signal(fence->fence->semaphore);
|
||||
[fence->fence->fence setSignaledValue:0];
|
||||
[fence->fence->fence notifyListener:fence->fence->listener
|
||||
atValue:1
|
||||
block:^(id<MTLSharedEvent> ev, uint64_t val) {
|
||||
dispatch_semaphore_signal(fence->fence->semaphore);
|
||||
}];
|
||||
// dispatch_semaphore_signal(fence->fence->semaphore);
|
||||
// [fence->fence->fence setSignaledValue:0];
|
||||
// [fence->fence->fence notifyListener:fence->fence->listener
|
||||
// atValue:1
|
||||
// block:^(id<MTLSharedEvent> ev, uint64_t val) {
|
||||
// dispatch_semaphore_signal(fence->fence->semaphore);
|
||||
// }];
|
||||
}
|
||||
void gnDestroyFenceFn(struct gnFence_t* fence) {
|
||||
[fence->fence->fence release];
|
||||
[fence->fence->listener release];
|
||||
free(fence->fence);
|
||||
// [fence->fence->fence release];
|
||||
// [fence->fence->listener release];
|
||||
// free(fence->fence);
|
||||
}
|
||||
|
@@ -4,4 +4,5 @@
|
||||
|
||||
typedef struct gnPlatformSemaphore_t {
|
||||
id<MTLEvent> event;
|
||||
gnBool eventTriggered;
|
||||
} gnPlatformSemaphore;
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
gnReturnCode gnCreatePresentationQueue(gnPresentationQueue* presentationQueue, struct gnOutputDevice_t* device, struct gnPresentationQueueInfo_t presentationInfo){
|
||||
presentationQueue->outputDevice = device;
|
||||
presentationQueue->info = presentationInfo;
|
||||
return device->deviceFunctions->_gnCreatePresentationQueue(presentationQueue, device, presentationInfo);
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@ typedef struct gnPresentationQueue_t {
|
||||
gnBool valid;
|
||||
uint32_t imageCount;
|
||||
struct gnTexture_t* images;
|
||||
struct gnPresentationQueueInfo_t info;
|
||||
} gnPresentationQueue;
|
||||
|
||||
gnReturnCode gnCreatePresentationQueue(gnPresentationQueue* presentationQueue, struct gnOutputDevice_t* device, struct gnPresentationQueueInfo_t presentationInfo);
|
||||
|
@@ -65,7 +65,7 @@ uint32_t gnGetMaxImageCount(struct gnWindowSurface_t surface, struct gnPhysicalD
|
||||
uint32_t gnGetPreferredImageCount(struct gnWindowSurface_t surface, struct gnPhysicalDevice_t device) {
|
||||
struct gnSurfaceDetails_t surfaceDetails = surface.instance->functions->_gnGetSurfaceDetails(&surface, device);
|
||||
|
||||
uint32_t imageCount = surfaceDetails.minImageCount;
|
||||
uint32_t imageCount = surfaceDetails.minImageCount + 1;
|
||||
if (surfaceDetails.maxImageCount > 0 && imageCount > surfaceDetails.maxImageCount) {
|
||||
imageCount = surfaceDetails.maxImageCount;
|
||||
}
|
||||
|
Reference in New Issue
Block a user