Basic metal renderer (only rendering a triangle as of right now).
This commit is contained in:
parent
4e0549f270
commit
0fceec19a9
|
@ -389,7 +389,7 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha
|
||||||
#define CLANG_LIBS_COMMON \
|
#define CLANG_LIBS_COMMON \
|
||||||
"-framework Cocoa -framework QuartzCore " \
|
"-framework Cocoa -framework QuartzCore " \
|
||||||
"-framework CoreServices " \
|
"-framework CoreServices " \
|
||||||
"-framework OpenGL -framework IOKit "
|
"-framework OpenGL -framework IOKit -framework Metal -framework MetalKit "
|
||||||
|
|
||||||
#define CLANG_LIBS_X64 CLANG_LIBS_COMMON \
|
#define CLANG_LIBS_X64 CLANG_LIBS_COMMON \
|
||||||
FOREIGN "/x64/libfreetype-mac.a"
|
FOREIGN "/x64/libfreetype-mac.a"
|
||||||
|
@ -398,7 +398,7 @@ FOREIGN "/x64/libfreetype-mac.a"
|
||||||
FOREIGN "/x86/libfreetype-mac.a"
|
FOREIGN "/x86/libfreetype-mac.a"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# error gcc options not set for this platform
|
# error clang options not set for this platform
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/* 4coder Metal render implementation */
|
||||||
|
|
||||||
|
#undef clamp
|
||||||
|
#undef function
|
||||||
|
#import <simd/simd.h>
|
||||||
|
#import <MetalKit/MetalKit.h>
|
||||||
|
|
||||||
|
// Header shared between C code here, which executes Metal API commands, and .metal files, which
|
||||||
|
// uses these types as inputs to the shaders.
|
||||||
|
#import "AAPLShaderTypes.h"
|
||||||
|
|
||||||
|
#define function static
|
||||||
|
#define clamp(a,x,b) clamp_((a),(x),(b))
|
||||||
|
|
||||||
|
@interface FCoderMetalRenderer : NSObject<MTKViewDelegate>
|
||||||
|
- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation FCoderMetalRenderer{
|
||||||
|
id<MTLDevice> _device;
|
||||||
|
|
||||||
|
// The render pipeline generated from the vertex and fragment shaders in the .metal shader file.
|
||||||
|
id<MTLRenderPipelineState> _pipelineState;
|
||||||
|
|
||||||
|
// The command queue used to pass commands to the device.
|
||||||
|
id<MTLCommandQueue> _commandQueue;
|
||||||
|
|
||||||
|
// The current size of the view, used as an input to the vertex shader.
|
||||||
|
vector_uint2 _viewportSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView{
|
||||||
|
self = [super init];
|
||||||
|
if(self)
|
||||||
|
{
|
||||||
|
NSError *error = nil;
|
||||||
|
|
||||||
|
_device = mtkView.device;
|
||||||
|
|
||||||
|
// Load all the shader files with a .metal file extension in the project.
|
||||||
|
id<MTLLibrary> defaultLibrary = [_device newLibraryWithFile:@"shaders/AAPLShaders.metallib"
|
||||||
|
error:&error];
|
||||||
|
Assert(error == nil);
|
||||||
|
|
||||||
|
id<MTLFunction> vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"];
|
||||||
|
id<MTLFunction> fragmentFunction = [defaultLibrary newFunctionWithName:@"fragmentShader"];
|
||||||
|
|
||||||
|
// Configure a pipeline descriptor that is used to create a pipeline state.
|
||||||
|
MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
||||||
|
pipelineStateDescriptor.label = @"Simple Pipeline";
|
||||||
|
pipelineStateDescriptor.vertexFunction = vertexFunction;
|
||||||
|
pipelineStateDescriptor.fragmentFunction = fragmentFunction;
|
||||||
|
pipelineStateDescriptor.colorAttachments[0].pixelFormat = mtkView.colorPixelFormat;
|
||||||
|
|
||||||
|
_pipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor
|
||||||
|
error:&error];
|
||||||
|
|
||||||
|
// Pipeline State creation could fail if the pipeline descriptor isn't set up properly.
|
||||||
|
// If the Metal API validation is enabled, you can find out more information about what
|
||||||
|
// went wrong. (Metal API validation is enabled by default when a debug build is run
|
||||||
|
// from Xcode.)
|
||||||
|
NSAssert(_pipelineState, @"Failed to created pipeline state: %@", error);
|
||||||
|
|
||||||
|
// Create the command queue
|
||||||
|
_commandQueue = [_device newCommandQueue];
|
||||||
|
|
||||||
|
u32 max_buffer_size = (u32)[_device maxBufferLength];
|
||||||
|
printf("Max Buffer Size: %u - Which is %lu vertices\n", max_buffer_size, (max_buffer_size / sizeof(Render_Vertex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called whenever view changes orientation or is resized
|
||||||
|
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size{
|
||||||
|
// Save the size of the drawable to pass to the vertex shader.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called whenever the view needs to render a frame.
|
||||||
|
- (void)drawInMTKView:(nonnull MTKView *)view{
|
||||||
|
CGSize size = [view drawableSize];
|
||||||
|
_viewportSize.x = size.width;
|
||||||
|
_viewportSize.y = size.height;
|
||||||
|
|
||||||
|
static const AAPLVertex triangleVertices[] =
|
||||||
|
{
|
||||||
|
// 2D positions, RGBA colors
|
||||||
|
{ { 250, -250 }, { 1, 0, 0, 1 } },
|
||||||
|
{ { -250, -250 }, { 0, 1, 0, 1 } },
|
||||||
|
{ { 0, 250 }, { 0, 0, 1, 1 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a new command buffer for each render pass to the current drawable.
|
||||||
|
id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
|
||||||
|
commandBuffer.label = @"MyCommand";
|
||||||
|
|
||||||
|
// Obtain a renderPassDescriptor generated from the view's drawable textures.
|
||||||
|
MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;
|
||||||
|
|
||||||
|
if(renderPassDescriptor != nil)
|
||||||
|
{
|
||||||
|
// Create a render command encoder.
|
||||||
|
id<MTLRenderCommandEncoder> renderEncoder =
|
||||||
|
[commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
|
||||||
|
renderEncoder.label = @"MyRenderEncoder";
|
||||||
|
|
||||||
|
// Set the region of the drawable to draw into.
|
||||||
|
[renderEncoder setViewport:(MTLViewport){0.0, 0.0, (double)_viewportSize.x, (double)_viewportSize.y, 0.0, 1.0 }];
|
||||||
|
|
||||||
|
[renderEncoder setRenderPipelineState:_pipelineState];
|
||||||
|
|
||||||
|
// Pass in the parameter data.
|
||||||
|
[renderEncoder setVertexBytes:triangleVertices
|
||||||
|
length:sizeof(triangleVertices)
|
||||||
|
atIndex:AAPLVertexInputIndexVertices];
|
||||||
|
|
||||||
|
[renderEncoder setVertexBytes:&_viewportSize
|
||||||
|
length:sizeof(_viewportSize)
|
||||||
|
atIndex:AAPLVertexInputIndexViewportSize];
|
||||||
|
|
||||||
|
// Draw the triangle.
|
||||||
|
[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle
|
||||||
|
vertexStart:0
|
||||||
|
vertexCount:3];
|
||||||
|
|
||||||
|
[renderEncoder endEncoding];
|
||||||
|
|
||||||
|
// Schedule a present once the framebuffer is complete using the current drawable.
|
||||||
|
[commandBuffer presentDrawable:view.currentDrawable];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finalize rendering here & push the command buffer to the GPU.
|
||||||
|
[commandBuffer commit];
|
||||||
|
}
|
||||||
|
@end
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
See LICENSE folder for this sample’s licensing information.
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
Header containing types and enum constants shared between Metal shaders and C/ObjC source
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AAPLShaderTypes_h
|
||||||
|
#define AAPLShaderTypes_h
|
||||||
|
|
||||||
|
#undef clamp
|
||||||
|
#include <simd/simd.h>
|
||||||
|
#define clamp(a,x,b) clamp_((a),(x),(b))
|
||||||
|
|
||||||
|
// Buffer index values shared between shader and C code to ensure Metal shader buffer inputs
|
||||||
|
// match Metal API buffer set calls.
|
||||||
|
typedef enum AAPLVertexInputIndex
|
||||||
|
{
|
||||||
|
AAPLVertexInputIndexVertices = 0,
|
||||||
|
AAPLVertexInputIndexViewportSize = 1,
|
||||||
|
} AAPLVertexInputIndex;
|
||||||
|
|
||||||
|
// This structure defines the layout of vertices sent to the vertex
|
||||||
|
// shader. This header is shared between the .metal shader and C code, to guarantee that
|
||||||
|
// the layout of the vertex array in the C code matches the layout that the .metal
|
||||||
|
// vertex shader expects.
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
vector_float2 position;
|
||||||
|
vector_float4 color;
|
||||||
|
} AAPLVertex;
|
||||||
|
|
||||||
|
#endif /* AAPLShaderTypes_h */
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
See LICENSE folder for this sample’s licensing information.
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
Metal shaders used for this sample
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <metal_stdlib>
|
||||||
|
#include <simd/simd.h>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
// Include header shared between this Metal shader code and C code executing Metal API commands.
|
||||||
|
#import "AAPLShaderTypes.h"
|
||||||
|
|
||||||
|
// Vertex shader outputs and fragment shader inputs
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
// The [[position]] attribute of this member indicates that this value
|
||||||
|
// is the clip space position of the vertex when this structure is
|
||||||
|
// returned from the vertex function.
|
||||||
|
float4 position [[position]];
|
||||||
|
|
||||||
|
// Since this member does not have a special attribute, the rasterizer
|
||||||
|
// interpolates its value with the values of the other triangle vertices
|
||||||
|
// and then passes the interpolated value to the fragment shader for each
|
||||||
|
// fragment in the triangle.
|
||||||
|
float4 color;
|
||||||
|
|
||||||
|
} RasterizerData;
|
||||||
|
|
||||||
|
vertex RasterizerData
|
||||||
|
vertexShader(uint vertexID [[vertex_id]],
|
||||||
|
constant AAPLVertex *vertices [[buffer(AAPLVertexInputIndexVertices)]],
|
||||||
|
constant vector_uint2 *viewportSizePointer [[buffer(AAPLVertexInputIndexViewportSize)]])
|
||||||
|
{
|
||||||
|
RasterizerData out;
|
||||||
|
|
||||||
|
// Index into the array of positions to get the current vertex.
|
||||||
|
// The positions are specified in pixel dimensions (i.e. a value of 100
|
||||||
|
// is 100 pixels from the origin).
|
||||||
|
float2 pixelSpacePosition = vertices[vertexID].position.xy;
|
||||||
|
|
||||||
|
// Get the viewport size and cast to float.
|
||||||
|
vector_float2 viewportSize = vector_float2(*viewportSizePointer);
|
||||||
|
|
||||||
|
|
||||||
|
// To convert from positions in pixel space to positions in clip-space,
|
||||||
|
// divide the pixel coordinates by half the size of the viewport.
|
||||||
|
out.position = vector_float4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
out.position.xy = pixelSpacePosition / (viewportSize / 2.0);
|
||||||
|
|
||||||
|
// Pass the input color directly to the rasterizer.
|
||||||
|
out.color = vertices[vertexID].color;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment float4 fragmentShader(RasterizerData in [[stage_in]])
|
||||||
|
{
|
||||||
|
// Return the interpolated color.
|
||||||
|
return in.color;
|
||||||
|
}
|
||||||
|
|
|
@ -285,6 +285,9 @@ gl_render(Render_Target *t){
|
||||||
t->free_texture_first = 0;
|
t->free_texture_first = 0;
|
||||||
t->free_texture_last = 0;
|
t->free_texture_last = 0;
|
||||||
|
|
||||||
|
u32 all_vertex_count = 0;
|
||||||
|
|
||||||
|
u64 begin_draw = system_now_time();
|
||||||
for (Render_Group *group = t->group_first;
|
for (Render_Group *group = t->group_first;
|
||||||
group != 0;
|
group != 0;
|
||||||
group = group->next){
|
group = group->next){
|
||||||
|
@ -339,9 +342,18 @@ gl_render(Render_Target *t){
|
||||||
glDisableVertexAttribArray(gpu_program.vertex_c);
|
glDisableVertexAttribArray(gpu_program.vertex_c);
|
||||||
glDisableVertexAttribArray(gpu_program.vertex_ht);
|
glDisableVertexAttribArray(gpu_program.vertex_ht);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
all_vertex_count += vertex_count;
|
||||||
}
|
}
|
||||||
|
u64 end_draw = system_now_time();
|
||||||
|
printf("Draw time: %fs\n", mac_get_time_diff_sec(begin_draw, end_draw));
|
||||||
|
|
||||||
|
u64 begin_flush = system_now_time();
|
||||||
glFlush();
|
glFlush();
|
||||||
|
u64 end_flush = system_now_time();
|
||||||
|
printf("Flush time: %fs\n", mac_get_time_diff_sec(begin_flush, end_flush));
|
||||||
|
|
||||||
|
printf("Drawn %d Vertices\n", all_vertex_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
|
@ -273,11 +273,24 @@ mac_to_object(Plat_Handle handle){
|
||||||
#include <OpenGL/gl.h>
|
#include <OpenGL/gl.h>
|
||||||
#import "mac_4ed_opengl.mm"
|
#import "mac_4ed_opengl.mm"
|
||||||
|
|
||||||
|
#import "mac_4ed_metal.mm"
|
||||||
|
|
||||||
#include "4ed_font_provider_freetype.h"
|
#include "4ed_font_provider_freetype.h"
|
||||||
#include "4ed_font_provider_freetype.cpp"
|
#include "4ed_font_provider_freetype.cpp"
|
||||||
|
|
||||||
#import "mac_4ed_functions.mm"
|
#import "mac_4ed_functions.mm"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
global Key_Code keycode_lookup_table[255];
|
||||||
|
|
||||||
|
function void
|
||||||
|
mac_key_code_init(void){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
function void
|
function void
|
||||||
|
@ -326,8 +339,6 @@ mac_resize(NSWindow *window){
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
// TODO(yuval): mac_resize(bounds.size.width, bounds.size.height);
|
|
||||||
|
|
||||||
@implementation FCoderAppDelegate
|
@implementation FCoderAppDelegate
|
||||||
- (void)applicationDidFinishLaunching:(id)sender{
|
- (void)applicationDidFinishLaunching:(id)sender{
|
||||||
}
|
}
|
||||||
|
@ -376,6 +387,13 @@ mac_resize(NSWindow *window){
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)drawRect:(NSRect)bounds{
|
- (void)drawRect:(NSRect)bounds{
|
||||||
|
/* NOTE(yuval): Force the graphics context to clear to black so we don't
|
||||||
|
get a flash of white until the app is ready to draw. In practice on modern macOS,
|
||||||
|
this only gets called for window creation and other extraordinary events.
|
||||||
|
(Taken From SDL) */
|
||||||
|
[[NSColor blackColor] setFill];
|
||||||
|
NSRectFill(bounds);
|
||||||
|
|
||||||
// NOTE(yuval): Read comment in win32_4ed.cpp's main loop
|
// NOTE(yuval): Read comment in win32_4ed.cpp's main loop
|
||||||
system_mutex_release(mac_vars.global_frame_mutex);
|
system_mutex_release(mac_vars.global_frame_mutex);
|
||||||
|
|
||||||
|
@ -422,7 +440,8 @@ mac_resize(NSWindow *window){
|
||||||
[NSApp terminate:nil];
|
[NSApp terminate:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
mac_gl_render(&target);
|
// mac_gl_render(&target);
|
||||||
|
mac_metal_render(&target);
|
||||||
|
|
||||||
mac_vars.first = false;
|
mac_vars.first = false;
|
||||||
|
|
||||||
|
@ -670,17 +689,19 @@ main(int arg_count, char **args){
|
||||||
|
|
||||||
NSView* content_view = [mac_vars.window contentView];
|
NSView* content_view = [mac_vars.window contentView];
|
||||||
|
|
||||||
// NOTE(yuval): Initialize the renderer
|
|
||||||
mac_gl_init(mac_vars.window);
|
|
||||||
|
|
||||||
// NOTE(yuval): Create the 4coder view
|
// NOTE(yuval): Create the 4coder view
|
||||||
mac_vars.view = [[FCoderView alloc] init];
|
mac_vars.view = [[FCoderView alloc] init];
|
||||||
[mac_vars.view setFrame:[content_view bounds]];
|
[mac_vars.view setFrame:[content_view bounds]];
|
||||||
[mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
[mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||||
|
|
||||||
|
// NOTE(yuval): Display window and view
|
||||||
[content_view addSubview:mac_vars.view];
|
[content_view addSubview:mac_vars.view];
|
||||||
[mac_vars.window makeKeyAndOrderFront:nil];
|
[mac_vars.window makeKeyAndOrderFront:nil];
|
||||||
|
|
||||||
|
// NOTE(yuval): Initialize the renderer
|
||||||
|
mac_gl_init(mac_vars.window);
|
||||||
|
mac_metal_init(mac_vars.window);
|
||||||
|
|
||||||
mac_resize(w, h);
|
mac_resize(w, h);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#import "metal/4ed_metal_render.mm"
|
||||||
|
|
||||||
|
global MTKView *metal_view;
|
||||||
|
global FCoderMetalRenderer *metal_renderer;
|
||||||
|
|
||||||
|
function void
|
||||||
|
mac_metal_init(NSWindow *window){
|
||||||
|
// NOTE(yuval): Create Metal view
|
||||||
|
NSView *content_view = [window contentView];
|
||||||
|
|
||||||
|
metal_view = [[MTKView alloc] initWithFrame:[content_view bounds]];
|
||||||
|
[metal_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||||
|
|
||||||
|
metal_view.device = MTLCreateSystemDefaultDevice();
|
||||||
|
|
||||||
|
// NOTE(yuval): Add the Metal view as a subview of the window
|
||||||
|
[content_view addSubview:metal_view];
|
||||||
|
|
||||||
|
// NOTE(yuval): Create the Metal renderer
|
||||||
|
metal_renderer = [[FCoderMetalRenderer alloc] initWithMetalKitView:metal_view];
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
mac_metal_render(Render_Target* target){
|
||||||
|
u64 begin_time = system_now_time();
|
||||||
|
[metal_renderer drawInMTKView:metal_view];
|
||||||
|
u64 end_time = system_now_time();
|
||||||
|
printf("Metal Render Time: %fs\n\n", mac_get_time_diff_sec(begin_time, end_time));
|
||||||
|
}
|
|
@ -5,6 +5,11 @@
|
||||||
#define GL_FUNC(N,R,P) typedef R (CALL_CONVENTION N##_Function)P; N##_Function *N = 0;
|
#define GL_FUNC(N,R,P) typedef R (CALL_CONVENTION N##_Function)P; N##_Function *N = 0;
|
||||||
#include "mac_4ed_opengl_funcs.h"
|
#include "mac_4ed_opengl_funcs.h"
|
||||||
|
|
||||||
|
f64 mac_get_time_diff_sec(u64 begin, u64 end){
|
||||||
|
f64 result = ((end - begin) / 1000000.0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#include "opengl/4ed_opengl_render.cpp"
|
#include "opengl/4ed_opengl_render.cpp"
|
||||||
|
|
||||||
@interface OpenGLView : NSOpenGLView
|
@interface OpenGLView : NSOpenGLView
|
||||||
|
@ -12,8 +17,6 @@
|
||||||
- (void)render:(Render_Target*)target;
|
- (void)render:(Render_Target*)target;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
global OpenGLView *opengl_view;
|
|
||||||
|
|
||||||
@implementation OpenGLView{
|
@implementation OpenGLView{
|
||||||
b32 glIsInitialized;
|
b32 glIsInitialized;
|
||||||
}
|
}
|
||||||
|
@ -95,14 +98,35 @@ global OpenGLView *opengl_view;
|
||||||
- (void)render:(Render_Target*)target{
|
- (void)render:(Render_Target*)target{
|
||||||
Assert(glIsInitialized);
|
Assert(glIsInitialized);
|
||||||
|
|
||||||
|
u64 context_lock_begin = system_now_time();
|
||||||
CGLLockContext([[self openGLContext] CGLContextObj]);
|
CGLLockContext([[self openGLContext] CGLContextObj]);
|
||||||
|
u64 context_lock_end = system_now_time();
|
||||||
|
printf("Context lock time: %fs\n", mac_get_time_diff_sec(context_lock_begin, context_lock_end));
|
||||||
|
|
||||||
|
u64 make_current_context_begin = system_now_time();
|
||||||
[[self openGLContext] makeCurrentContext];
|
[[self openGLContext] makeCurrentContext];
|
||||||
|
u64 make_current_context_end = system_now_time();
|
||||||
|
printf("Make current context time: %fs\n", mac_get_time_diff_sec(make_current_context_begin, make_current_context_end));
|
||||||
|
|
||||||
|
u64 gl_render_begin = system_now_time();
|
||||||
gl_render(target);
|
gl_render(target);
|
||||||
|
u64 gl_render_end = system_now_time();
|
||||||
|
printf("GL render time: %fs\n", mac_get_time_diff_sec(gl_render_begin, gl_render_end));
|
||||||
|
|
||||||
|
u64 gl_flush_buffer_begin = system_now_time();
|
||||||
[[self openGLContext] flushBuffer];
|
[[self openGLContext] flushBuffer];
|
||||||
|
u64 gl_flush_buffer_end = system_now_time();
|
||||||
|
printf("GL flush buffer time: %fs\n", mac_get_time_diff_sec(gl_flush_buffer_begin, gl_flush_buffer_end));
|
||||||
|
|
||||||
|
u64 context_unlock_begin = system_now_time();
|
||||||
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
||||||
|
u64 context_unlock_end = system_now_time();
|
||||||
|
printf("Context unlock time: %fs\n", mac_get_time_diff_sec(context_unlock_begin, context_unlock_end));
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
global OpenGLView *opengl_view;
|
||||||
|
|
||||||
function void
|
function void
|
||||||
mac_gl_init(NSWindow *window){
|
mac_gl_init(NSWindow *window){
|
||||||
// NOTE(yuval): Create OpenGLView
|
// NOTE(yuval): Create OpenGLView
|
||||||
|
@ -125,8 +149,8 @@ mac_gl_init(NSWindow *window){
|
||||||
|
|
||||||
function void
|
function void
|
||||||
mac_gl_render(Render_Target* target){
|
mac_gl_render(Render_Target* target){
|
||||||
f64 begin_time = system_now_time() / 1000000.0;
|
u64 begin_time = system_now_time();
|
||||||
[opengl_view render:target];
|
[opengl_view render:target];
|
||||||
f64 end_time = system_now_time() / 1000000.0;
|
u64 end_time = system_now_time();
|
||||||
printf("Render Time: %fs\n", (end_time - begin_time));
|
printf("Render Time: %fs\n\n", mac_get_time_diff_sec(begin_time, end_time));
|
||||||
}
|
}
|
Loading…
Reference in New Issue