metal commands
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "core/command/command_buffer/gryphn_command_buffer.h"
|
||||||
|
#include "core/pipelines/graphics_pipeline/gryphn_graphics_pipeline.h"
|
||||||
|
#import <Metal/MTLCommandBuffer.h>
|
||||||
|
#import <Metal/MTLCommandEncoder.h>
|
||||||
|
|
||||||
|
typedef struct gnPlatformCommandBuffer_t {
|
||||||
|
id<MTLCommandBuffer> commandBuffer;
|
||||||
|
id<MTLCommandEncoder> encoder;
|
||||||
|
struct gnGraphicsPipeline_t* boundGraphcisPipeline;
|
||||||
|
} gnPlatformCommandBuffer;
|
@@ -0,0 +1,21 @@
|
|||||||
|
#include "metal_command_buffer.h"
|
||||||
|
#include "core/commands/command_pool/metal_command_pool.h"
|
||||||
|
#import <Metal/Metal.h>
|
||||||
|
|
||||||
|
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) {
|
||||||
|
commandBuffer->commandBuffer->boundGraphcisPipeline = NULL;
|
||||||
|
return GN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
gnReturnCode gnEndCommandBuffer(struct gnCommandBuffer_t* commandBuffer) {
|
||||||
|
return GN_SUCCESS;
|
||||||
|
}
|
@@ -4,6 +4,7 @@
|
|||||||
gnReturnCode gnCreateCommandPoolFn(struct gnCommandPool_t* commandPool, struct gnOutputDevice_t* device, struct gnCommandPoolInfo_t info) {
|
gnReturnCode gnCreateCommandPoolFn(struct gnCommandPool_t* commandPool, struct gnOutputDevice_t* device, struct gnCommandPoolInfo_t info) {
|
||||||
commandPool->commandPool = malloc(sizeof(struct gnPlatformCommandPool_t));
|
commandPool->commandPool = malloc(sizeof(struct gnPlatformCommandPool_t));
|
||||||
commandPool->commandPool->commandQueue = [device->outputDevice->device newCommandQueue];
|
commandPool->commandPool->commandQueue = [device->outputDevice->device newCommandQueue];
|
||||||
|
|
||||||
return GN_SUCCESS;
|
return GN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,85 @@
|
|||||||
|
#include "core/command/commands/gryphn_command.h"
|
||||||
|
#include "core/framebuffers/metal_framebuffer.h"
|
||||||
|
#include "core/commands/command_buffer/metal_command_buffer.h"
|
||||||
|
#include "core/pipelines/graphics_pipeline/metal_graphics_pipeline.h"
|
||||||
|
#import <Metal/MTLRenderCommandEncoder.h>
|
||||||
|
|
||||||
|
void gnCommandBeginRenderPassFn(struct gnCommandBuffer_t* buffer, struct gnRenderPassInfo_t passInfo) {
|
||||||
|
int currentColorAttachment = 0;
|
||||||
|
for (int i = 0; i < passInfo.clearValueCount; i++) {
|
||||||
|
gnBool wasDepthStencil = gnFalse;
|
||||||
|
if (isDepthFormat(passInfo.renderPassDescriptor->info.attachmentInfos[i].format)) {
|
||||||
|
wasDepthStencil = gnTrue;
|
||||||
|
}
|
||||||
|
if (isStencilFormat(passInfo.renderPassDescriptor->info.attachmentInfos[i].format)) {
|
||||||
|
wasDepthStencil = gnTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!wasDepthStencil) {
|
||||||
|
MTLRenderPassColorAttachmentDescriptor* color = passInfo.framebuffer->framebuffer->framebuffer.colorAttachments[i];
|
||||||
|
color.clearColor = MTLClearColorMake(
|
||||||
|
passInfo.clearValues[i].red,
|
||||||
|
passInfo.clearValues[i].green,
|
||||||
|
passInfo.clearValues[i].blue,
|
||||||
|
passInfo.clearValues[i].alpha
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer->commandBuffer->encoder = [buffer->commandBuffer->commandBuffer renderCommandEncoderWithDescriptor:passInfo.framebuffer->framebuffer->framebuffer];
|
||||||
|
MTLViewport vp = {(double)passInfo.offset.x, (double)passInfo.offset.y, (double)passInfo.size.x, (double)passInfo.size.y, 0.0f, 1.0f};
|
||||||
|
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
|
||||||
|
[encoder setViewport:vp];
|
||||||
|
}
|
||||||
|
void gnCommandEndRenderPassFn(struct gnCommandBuffer_t* buffer) {
|
||||||
|
[buffer->commandBuffer->encoder endEncoding];
|
||||||
|
}
|
||||||
|
void gnCommandBindGraphicsPipelineFn(struct gnCommandBuffer_t* buffer, struct gnGraphicsPipeline_t* graphicsPipeline) {
|
||||||
|
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
|
||||||
|
[encoder setRenderPipelineState:graphicsPipeline->graphicsPipeline->graphicsPipeline];
|
||||||
|
|
||||||
|
if (graphicsPipeline->info.cullMode.face == GN_CULL_FACE_BACK)
|
||||||
|
[encoder setCullMode:MTLCullModeBack];
|
||||||
|
else if (graphicsPipeline->info.cullMode.face == GN_CULL_FACE_FRONT)
|
||||||
|
[encoder setCullMode:MTLCullModeFront];
|
||||||
|
else if (graphicsPipeline->info.cullMode.face == GN_CULL_FACE_NONE)
|
||||||
|
[encoder setCullMode:MTLCullModeNone];
|
||||||
|
|
||||||
|
if (graphicsPipeline->info.cullMode.direction == GN_DIRECTION_CLOCK_WISE)
|
||||||
|
[encoder setFrontFacingWinding:MTLWindingCounterClockwise];
|
||||||
|
if (graphicsPipeline->info.cullMode.direction == GN_DIRECTION_COUNTER_CLOCK_WISE)
|
||||||
|
[encoder setFrontFacingWinding:MTLWindingClockwise];
|
||||||
|
|
||||||
|
if (graphicsPipeline->info.fillMode == GN_FILL_MODE_POINT)
|
||||||
|
[encoder setTriangleFillMode:MTLTriangleFillModeFill];
|
||||||
|
if (graphicsPipeline->info.fillMode == GN_FILL_MODE_LINE)
|
||||||
|
[encoder setTriangleFillMode:MTLTriangleFillModeLines];
|
||||||
|
if (graphicsPipeline->info.fillMode == GN_FILL_MODE_FILL)
|
||||||
|
[encoder setTriangleFillMode:MTLTriangleFillModeFill];
|
||||||
|
|
||||||
|
buffer->commandBuffer->boundGraphcisPipeline = graphicsPipeline;
|
||||||
|
}
|
||||||
|
void gnCommandSetViewportFn(struct gnCommandBuffer_t* buffer, struct gnViewport_t viewport) {
|
||||||
|
MTLViewport vp = {(double)viewport.position.x, (double)viewport.position.y, (double)viewport.size.x, (double)viewport.size.y, viewport.minDepth, viewport.maxDepth};
|
||||||
|
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
|
||||||
|
[encoder setViewport:vp];
|
||||||
|
}
|
||||||
|
void gnCommandSetScissorFn(struct gnCommandBuffer_t* buffer, struct gnScissor_t scissor) {
|
||||||
|
MTLScissorRect scissorRect = { scissor.position.x, scissor.position.y, scissor.size.x, scissor.size.y };
|
||||||
|
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
|
||||||
|
[encoder setScissorRect:scissorRect];
|
||||||
|
}
|
||||||
|
void gnCommandDrawFn(struct gnCommandBuffer_t* buffer, int vertexCount, int firstVertex, int instanceCount, int firstInstance) {
|
||||||
|
if (buffer->commandBuffer->boundGraphcisPipeline != NULL) {
|
||||||
|
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
|
||||||
|
if (buffer->commandBuffer->boundGraphcisPipeline->info.primitiveType == GN_PRIMITIVE_POINTS)
|
||||||
|
[encoder drawPrimitives:MTLPrimitiveTypePoint vertexStart:firstVertex vertexCount:vertexCount instanceCount:instanceCount baseInstance:firstInstance];
|
||||||
|
else if (buffer->commandBuffer->boundGraphcisPipeline->info.primitiveType == GN_PRIMITIVE_LINES)
|
||||||
|
[encoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:firstVertex vertexCount:vertexCount instanceCount:instanceCount baseInstance:firstInstance];
|
||||||
|
else if (buffer->commandBuffer->boundGraphcisPipeline->info.primitiveType == GN_PRIMITIVE_LINE_STRIP)
|
||||||
|
[encoder drawPrimitives:MTLPrimitiveTypeLineStrip vertexStart:firstVertex vertexCount:vertexCount instanceCount:instanceCount baseInstance:firstInstance];
|
||||||
|
else if (buffer->commandBuffer->boundGraphcisPipeline->info.primitiveType == GN_PRIMITIVE_TRIANGLES)
|
||||||
|
[encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:firstVertex vertexCount:vertexCount instanceCount:instanceCount baseInstance:firstInstance];
|
||||||
|
else if (buffer->commandBuffer->boundGraphcisPipeline->info.primitiveType == GN_PRIMITIVE_TRIANGLE_STRIP)
|
||||||
|
[encoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:firstVertex vertexCount:vertexCount instanceCount:instanceCount baseInstance:firstInstance];
|
||||||
|
}
|
||||||
|
}
|
@@ -6,3 +6,6 @@
|
|||||||
typedef struct gnPlatformFramebuffer_t {
|
typedef struct gnPlatformFramebuffer_t {
|
||||||
MTLRenderPassDescriptor* framebuffer;
|
MTLRenderPassDescriptor* framebuffer;
|
||||||
} gnPlatformFramebuffer;
|
} gnPlatformFramebuffer;
|
||||||
|
|
||||||
|
gnBool isDepthFormat(gnImageFormat format);
|
||||||
|
gnBool isStencilFormat(gnImageFormat format);
|
||||||
|
@@ -38,6 +38,7 @@ gnReturnCode gnCreateFramebufferFn(struct gnFramebuffer_t* framebuffer, struct g
|
|||||||
[framebuffer->framebuffer->framebuffer setRenderTargetWidth:info.size.x];
|
[framebuffer->framebuffer->framebuffer setRenderTargetWidth:info.size.x];
|
||||||
[framebuffer->framebuffer->framebuffer setRenderTargetHeight:info.size.y];
|
[framebuffer->framebuffer->framebuffer setRenderTargetHeight:info.size.y];
|
||||||
|
|
||||||
|
int colorAttachment = 0;
|
||||||
for (int i = 0; i < info.renderPassDescriptor->info.attachmentCount; i++) {
|
for (int i = 0; i < info.renderPassDescriptor->info.attachmentCount; i++) {
|
||||||
gnBool wasDepthStencil = gnFalse;
|
gnBool wasDepthStencil = gnFalse;
|
||||||
if (isDepthFormat(info.renderPassDescriptor->info.attachmentInfos[i].format)) {
|
if (isDepthFormat(info.renderPassDescriptor->info.attachmentInfos[i].format)) {
|
||||||
@@ -54,7 +55,7 @@ gnReturnCode gnCreateFramebufferFn(struct gnFramebuffer_t* framebuffer, struct g
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!wasDepthStencil) {
|
if(!wasDepthStencil) {
|
||||||
MTLRenderPassColorAttachmentDescriptor* color = framebuffer->framebuffer->framebuffer.colorAttachments[i];
|
MTLRenderPassColorAttachmentDescriptor* color = framebuffer->framebuffer->framebuffer.colorAttachments[colorAttachment];
|
||||||
color.texture = info.attachments[i].texture->texture;
|
color.texture = info.attachments[i].texture->texture;
|
||||||
|
|
||||||
color.loadAction = mtlGryphnLoadOperation(info.renderPassDescriptor->info.attachmentInfos[i].loadOperation);
|
color.loadAction = mtlGryphnLoadOperation(info.renderPassDescriptor->info.attachmentInfos[i].loadOperation);
|
||||||
@@ -62,6 +63,8 @@ gnReturnCode gnCreateFramebufferFn(struct gnFramebuffer_t* framebuffer, struct g
|
|||||||
|
|
||||||
if (color.loadAction == MTLLoadActionClear)
|
if (color.loadAction == MTLLoadActionClear)
|
||||||
color.clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 1.0);
|
color.clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
colorAttachment++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
gnReturnCode gnCreateGraphicsPipeline(struct gnGraphicsPipeline_t* graphicsPipeline, struct gnOutputDevice_t* device, struct gnGraphicsPipelineInfo_t info) {
|
gnReturnCode gnCreateGraphicsPipeline(struct gnGraphicsPipeline_t* graphicsPipeline, struct gnOutputDevice_t* device, struct gnGraphicsPipelineInfo_t info) {
|
||||||
graphicsPipeline->device = device;
|
graphicsPipeline->device = device;
|
||||||
|
graphicsPipeline->info = info;
|
||||||
return graphicsPipeline->device->deviceFunctions->_gnCreateGraphicsPipeline(graphicsPipeline, device, info);
|
return graphicsPipeline->device->deviceFunctions->_gnCreateGraphicsPipeline(graphicsPipeline, device, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -94,6 +94,7 @@ struct gnPlatformGraphicsPipeline_t;
|
|||||||
typedef struct gnGraphicsPipeline_t {
|
typedef struct gnGraphicsPipeline_t {
|
||||||
struct gnPlatformGraphicsPipeline_t* graphicsPipeline;
|
struct gnPlatformGraphicsPipeline_t* graphicsPipeline;
|
||||||
struct gnOutputDevice_t* device;
|
struct gnOutputDevice_t* device;
|
||||||
|
struct gnGraphicsPipelineInfo_t info;
|
||||||
} gnGraphicsPipeline;
|
} gnGraphicsPipeline;
|
||||||
|
|
||||||
gnReturnCode gnCreateGraphicsPipeline(struct gnGraphicsPipeline_t* graphicsPipeline, struct gnOutputDevice_t* device, struct gnGraphicsPipelineInfo_t info);
|
gnReturnCode gnCreateGraphicsPipeline(struct gnGraphicsPipeline_t* graphicsPipeline, struct gnOutputDevice_t* device, struct gnGraphicsPipelineInfo_t info);
|
||||||
|
Reference in New Issue
Block a user