multisampling in metal
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
#include "metal_commands.h"
|
#include "metal_commands.h"
|
||||||
#include "shader_module/metal_shader_module.h"
|
#include "shader_module/metal_shader_module.h"
|
||||||
|
#include "renderpass/metal_render_pass.h"
|
||||||
|
#include "utils/math/gryphn_math.h"
|
||||||
|
|
||||||
void metelBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo) {
|
void metelBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo) {
|
||||||
int currentColorAttachment = 0;
|
int currentColorAttachment = 0;
|
||||||
@@ -127,8 +129,9 @@ void metalBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t
|
|||||||
];
|
];
|
||||||
} else if (uniform->uniform->bindings[i].type == GN_IMAGE_DESCRIPTOR) {
|
} else if (uniform->uniform->bindings[i].type == GN_IMAGE_DESCRIPTOR) {
|
||||||
gnImageUniformInfo info = *(gnImageUniformInfo*)uniform->uniform->bindings[i].data;
|
gnImageUniformInfo info = *(gnImageUniformInfo*)uniform->uniform->bindings[i].data;
|
||||||
[encoder setFragmentTexture:info.texture->texture->texture atIndex:
|
uint32_t index = buffer->commandBuffer->boundGraphcisPipeline->graphicsPipeline->fragmentShaderMaps.sets[set].bindings[info.binding];
|
||||||
buffer->commandBuffer->boundGraphcisPipeline->graphicsPipeline->fragmentShaderMaps.sets[set].bindings[info.binding]];
|
[encoder setFragmentTexture:info.texture->texture->texture atIndex:index];
|
||||||
|
[encoder setFragmentSamplerState:info.texture->texture->sampler atIndex:index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,12 +9,6 @@ gnReturnCode createMetalOutputDevice(gnOutputDeviceHandle outputDevice, gnInstan
|
|||||||
outputDevice->outputDevice = malloc(sizeof(gnPlatformOutputDevice));
|
outputDevice->outputDevice = malloc(sizeof(gnPlatformOutputDevice));
|
||||||
outputDevice->outputDevice->device = deviceInfo.physicalDevice.physicalDevice->device.retain;
|
outputDevice->outputDevice->device = deviceInfo.physicalDevice.physicalDevice->device.retain;
|
||||||
outputDevice->outputDevice->transferQueue = outputDevice->outputDevice->device.newCommandQueue;
|
outputDevice->outputDevice->transferQueue = 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;
|
return GN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,7 +14,6 @@ struct gnPlatformOutputDevice_t {
|
|||||||
|
|
||||||
id<MTLCommandBuffer> executingCommandBuffer;
|
id<MTLCommandBuffer> executingCommandBuffer;
|
||||||
id<MTLCommandQueue> transferQueue;
|
id<MTLCommandQueue> transferQueue;
|
||||||
// id<MTLRenderPipelineState> framebuffer;
|
|
||||||
} gnPlatformOutputDevice;
|
} gnPlatformOutputDevice;
|
||||||
|
|
||||||
gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCount);
|
gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCount);
|
||||||
|
@@ -28,6 +28,13 @@ MTLStoreAction mtlGryphnStoreOperation(gnStoreOperation storeOperation) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTLStoreAction mtlGryphnStoreOperationResolve(gnStoreOperation storeOperation) {
|
||||||
|
switch (storeOperation) {
|
||||||
|
case GN_STORE_OPERATION_STORE: return MTLStoreActionStoreAndMultisampleResolve;
|
||||||
|
case GN_STORE_OPERATION_DONT_CARE: return MTLStoreActionDontCare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gnReturnCode createMetalFramebuffer(gnFramebuffer framebuffer, gnOutputDevice device, gnFramebufferInfo info) {
|
gnReturnCode createMetalFramebuffer(gnFramebuffer framebuffer, gnOutputDevice device, gnFramebufferInfo info) {
|
||||||
framebuffer->framebuffer = malloc(sizeof(struct gnPlatformFramebuffer_t));
|
framebuffer->framebuffer = malloc(sizeof(struct gnPlatformFramebuffer_t));
|
||||||
if (info.attachmentCount != info.renderPassDescriptor->info.attachmentCount) {
|
if (info.attachmentCount != info.renderPassDescriptor->info.attachmentCount) {
|
||||||
@@ -45,13 +52,20 @@ gnReturnCode createMetalFramebuffer(gnFramebuffer framebuffer, gnOutputDevice de
|
|||||||
[framebuffer->framebuffer->subpasses[i] setRenderTargetWidth:info.size.x];
|
[framebuffer->framebuffer->subpasses[i] setRenderTargetWidth:info.size.x];
|
||||||
[framebuffer->framebuffer->subpasses[i] setRenderTargetHeight:info.size.y];
|
[framebuffer->framebuffer->subpasses[i] setRenderTargetHeight:info.size.y];
|
||||||
|
|
||||||
|
gnBool resolve = !(info.renderPassDescriptor->info.subpassInfos[i].resolveAttachments == NULL);
|
||||||
|
|
||||||
for (int c = 0; c < info.renderPassDescriptor->info.subpassInfos[i].colorAttachmentCount; c++) {
|
for (int c = 0; c < info.renderPassDescriptor->info.subpassInfos[i].colorAttachmentCount; c++) {
|
||||||
uint32_t attachmentIndex = info.renderPassDescriptor->info.subpassInfos[i].colorAttachments[i].index;
|
uint32_t attachmentIndex = info.renderPassDescriptor->info.subpassInfos[i].colorAttachments[c].index, resolveAttachemntIndex = 0;
|
||||||
MTLRenderPassColorAttachmentDescriptor* color = framebuffer->framebuffer->subpasses[i].colorAttachments[c];
|
MTLRenderPassColorAttachmentDescriptor* color = framebuffer->framebuffer->subpasses[i].colorAttachments[c];
|
||||||
color.texture = info.attachments[attachmentIndex]->texture->texture;
|
color.texture = info.attachments[attachmentIndex]->texture->texture;
|
||||||
|
if (resolve) {
|
||||||
|
resolveAttachemntIndex = info.renderPassDescriptor->info.subpassInfos[i].resolveAttachments[c].index;
|
||||||
|
color.resolveTexture = info.attachments[resolveAttachemntIndex]->texture->texture;
|
||||||
|
color.storeAction = mtlGryphnStoreOperationResolve(info.renderPassDescriptor->info.attachmentInfos[attachmentIndex].storeOperation);
|
||||||
|
} else {
|
||||||
|
color.storeAction = mtlGryphnStoreOperation(info.renderPassDescriptor->info.attachmentInfos[attachmentIndex].storeOperation);
|
||||||
|
}
|
||||||
color.loadAction = mtlGryphnLoadOperation(info.renderPassDescriptor->info.attachmentInfos[attachmentIndex].loadOperation);
|
color.loadAction = mtlGryphnLoadOperation(info.renderPassDescriptor->info.attachmentInfos[attachmentIndex].loadOperation);
|
||||||
color.storeAction = mtlGryphnStoreOperation(info.renderPassDescriptor->info.attachmentInfos[attachmentIndex].storeOperation);
|
|
||||||
|
|
||||||
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);
|
||||||
@@ -66,7 +80,7 @@ gnReturnCode createMetalFramebuffer(gnFramebuffer framebuffer, gnOutputDevice de
|
|||||||
depthAttachment.clearDepth = 1.0f;
|
depthAttachment.clearDepth = 1.0f;
|
||||||
|
|
||||||
MTLRenderPassStencilAttachmentDescriptor* stencilAttachment = framebuffer->framebuffer->subpasses[attachmentIndex].stencilAttachment;
|
MTLRenderPassStencilAttachmentDescriptor* stencilAttachment = framebuffer->framebuffer->subpasses[attachmentIndex].stencilAttachment;
|
||||||
stencilAttachment.texture = info.attachments[i]->texture->texture;
|
stencilAttachment.texture = info.attachments[attachmentIndex]->texture->texture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
#include "debugger/gryphn_debugger.h"
|
#include "debugger/gryphn_debugger.h"
|
||||||
#include "shader_module/metal_shader_module.h"
|
#include "shader_module/metal_shader_module.h"
|
||||||
#include "surface/metal_surface.h"
|
#include "surface/metal_surface.h"
|
||||||
|
#include "texture/metal_texture.h"
|
||||||
|
|
||||||
#include "utils/math/gryphn_vec3.h"
|
#include "utils/math/gryphn_vec3.h"
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ MTLCompareFunction mtlGrypnCompareOperation(gnCompareOperation operation) {
|
|||||||
gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info) {
|
gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info) {
|
||||||
graphicsPipeline->graphicsPipeline = malloc(sizeof(struct gnPlatformGraphicsPipeline_t));
|
graphicsPipeline->graphicsPipeline = malloc(sizeof(struct gnPlatformGraphicsPipeline_t));
|
||||||
MTLRenderPipelineDescriptor* descriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
MTLRenderPipelineDescriptor* descriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
||||||
|
descriptor.rasterSampleCount = mtlSampleCount(info.multisample.samples);
|
||||||
|
|
||||||
if (info.subpassIndex >= info.renderPassDescriptor->info.subpassCount) {
|
if (info.subpassIndex >= info.renderPassDescriptor->info.subpassCount) {
|
||||||
gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){
|
gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){
|
||||||
|
@@ -19,7 +19,6 @@ gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) {
|
|||||||
}];
|
}];
|
||||||
|
|
||||||
id<MTLBlitCommandEncoder> blit = [commandBuffer blitCommandEncoder];
|
id<MTLBlitCommandEncoder> blit = [commandBuffer blitCommandEncoder];
|
||||||
|
|
||||||
[blit copyFromTexture:info.presentationQueues[i]->images[info.imageIndices[i]]->texture->texture
|
[blit copyFromTexture:info.presentationQueues[i]->images[info.imageIndices[i]]->texture->texture
|
||||||
sourceSlice:0
|
sourceSlice:0
|
||||||
sourceLevel:0
|
sourceLevel:0
|
||||||
|
@@ -18,6 +18,11 @@ void destroyMetalWindowSurface(gnWindowSurface windowSurface) {
|
|||||||
free(windowSurface->windowSurface);
|
free(windowSurface->windowSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gnImageFormat mtlMetalFormatToGryphn(MTLPixelFormat format) {
|
||||||
|
if (format == MTLPixelFormatBGRA8Unorm_sRGB) return GN_FORMAT_BGRA8_SRGB;
|
||||||
|
return GN_FORMAT_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
gnSurfaceDetails getMetalSurfaceDetails(
|
gnSurfaceDetails getMetalSurfaceDetails(
|
||||||
gnWindowSurface windowSurface, gnPhysicalDevice device
|
gnWindowSurface windowSurface, gnPhysicalDevice device
|
||||||
) {
|
) {
|
||||||
@@ -35,6 +40,7 @@ MTLPixelFormat mtlGryphnFormatToMetalFormat(gnImageFormat format) {
|
|||||||
switch (format) {
|
switch (format) {
|
||||||
case GN_FORMAT_NONE: return MTLPixelFormatInvalid;
|
case GN_FORMAT_NONE: return MTLPixelFormatInvalid;
|
||||||
case GN_FORMAT_BGRA8_SRGB: return MTLPixelFormatBGRA8Unorm_sRGB;
|
case GN_FORMAT_BGRA8_SRGB: return MTLPixelFormatBGRA8Unorm_sRGB;
|
||||||
|
case GN_FORMAT_BGRA8: return MTLPixelFormatBGRA8Unorm;
|
||||||
case GN_FORMAT_RGBA8_SRGB: return MTLPixelFormatRGBA8Unorm_sRGB;
|
case GN_FORMAT_RGBA8_SRGB: return MTLPixelFormatRGBA8Unorm_sRGB;
|
||||||
case GN_FORMAT_D24S8_UINT: return MTLPixelFormatDepth24Unorm_Stencil8;
|
case GN_FORMAT_D24S8_UINT: return MTLPixelFormatDepth24Unorm_Stencil8;
|
||||||
case GN_FORMAT_D32S8_UINT: return MTLPixelFormatDepth32Float_Stencil8;
|
case GN_FORMAT_D32S8_UINT: return MTLPixelFormatDepth32Float_Stencil8;
|
||||||
@@ -43,6 +49,7 @@ MTLPixelFormat mtlGryphnFormatToMetalFormat(gnImageFormat format) {
|
|||||||
|
|
||||||
CGColorSpaceRef mtlGryphnColorSpaceToMetalColorSpace(gnColorSpace colorSpace) {
|
CGColorSpaceRef mtlGryphnColorSpaceToMetalColorSpace(gnColorSpace colorSpace) {
|
||||||
switch (colorSpace) {
|
switch (colorSpace) {
|
||||||
|
case GN_COLOR_SPACE_NONE: { return CGColorSpaceCreateWithName(kCGColorSpaceSRGB); } // very bad if here
|
||||||
case GN_COLOR_SPACE_SRGB_NONLINEAR: { return CGColorSpaceCreateWithName(kCGColorSpaceSRGB); }
|
case GN_COLOR_SPACE_SRGB_NONLINEAR: { return CGColorSpaceCreateWithName(kCGColorSpaceSRGB); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "textures/gryphn_texture.h"
|
#include "textures/gryphn_texture.h"
|
||||||
#import <Metal/MTLTexture.h>
|
#import <Metal/MTLTexture.h>
|
||||||
|
#import <Metal/MTLSampler.h>
|
||||||
|
|
||||||
typedef struct gnPlatformTexture_t {
|
typedef struct gnPlatformTexture_t {
|
||||||
id<MTLTexture> texture;
|
id<MTLTexture> texture;
|
||||||
|
id<MTLSamplerState> sampler;
|
||||||
} gnPlatformTexture;
|
} gnPlatformTexture;
|
||||||
|
|
||||||
gnReturnCode createMetalTexture(gnTexture texture, gnDevice device, const gnTextureInfo info);
|
gnReturnCode createMetalTexture(gnTexture texture, gnDevice device, const gnTextureInfo info);
|
||||||
void metalTextureData(gnTextureHandle texture, void* pixelData);
|
void metalTextureData(gnTextureHandle texture, void* pixelData);
|
||||||
void metalDestroyTexture(gnTexture texture);
|
void metalDestroyTexture(gnTexture texture);
|
||||||
|
|
||||||
|
|
||||||
|
NSUInteger mtlSampleCount(gnMultisampleCountFlags flags);
|
||||||
|
@@ -16,18 +16,30 @@ NSUInteger mtlSampleCount(gnMultisampleCountFlags flags) {
|
|||||||
gnReturnCode createMetalTexture(gnTexture texture, gnDevice device, const gnTextureInfo info) {
|
gnReturnCode createMetalTexture(gnTexture texture, gnDevice device, const gnTextureInfo info) {
|
||||||
texture->texture = malloc(sizeof(struct gnPlatformTexture_t));
|
texture->texture = malloc(sizeof(struct gnPlatformTexture_t));
|
||||||
MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init];
|
MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init];
|
||||||
textureDescriptor.pixelFormat = mtlGryphnFormatToMetalFormat(info.format);
|
|
||||||
textureDescriptor.width = info.extent.width;
|
textureDescriptor.width = info.extent.width;
|
||||||
textureDescriptor.height = info.extent.height;
|
textureDescriptor.height = info.extent.height;
|
||||||
textureDescriptor.depth = info.extent.depth;
|
textureDescriptor.depth = info.extent.depth;
|
||||||
textureDescriptor.sampleCount = mtlSampleCount(info.samples);
|
textureDescriptor.sampleCount = mtlSampleCount(info.samples);
|
||||||
if (textureDescriptor.sampleCount >= 2)
|
textureDescriptor.pixelFormat = mtlGryphnFormatToMetalFormat(info.format);
|
||||||
|
textureDescriptor.usage = MTLTextureUsageRenderTarget;
|
||||||
|
if (textureDescriptor.sampleCount >= 2) {
|
||||||
textureDescriptor.textureType = MTLTextureType2DMultisample;
|
textureDescriptor.textureType = MTLTextureType2DMultisample;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
textureDescriptor.textureType = MTLTextureType2D;
|
textureDescriptor.textureType = MTLTextureType2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTLSamplerDescriptor *samplerDesc = [[MTLSamplerDescriptor alloc] init];
|
||||||
|
samplerDesc.minFilter = MTLSamplerMinMagFilterLinear;
|
||||||
|
samplerDesc.magFilter = MTLSamplerMinMagFilterLinear;
|
||||||
|
samplerDesc.mipFilter = MTLSamplerMipFilterNotMipmapped;
|
||||||
|
samplerDesc.sAddressMode = MTLSamplerAddressModeClampToEdge;
|
||||||
|
samplerDesc.tAddressMode = MTLSamplerAddressModeClampToEdge;
|
||||||
|
samplerDesc.normalizedCoordinates = YES;
|
||||||
|
texture->texture->sampler = [device->outputDevice->device newSamplerStateWithDescriptor:samplerDesc];
|
||||||
texture->texture->texture = [device->outputDevice->device newTextureWithDescriptor:textureDescriptor];
|
texture->texture->texture = [device->outputDevice->device newTextureWithDescriptor:textureDescriptor];
|
||||||
[textureDescriptor release];
|
[textureDescriptor release];
|
||||||
|
[samplerDesc release];
|
||||||
return GN_SUCCESS;
|
return GN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -75,12 +75,13 @@ gnSurfaceFormat* vkGetSurfaceFormats(
|
|||||||
for (int i = 0; i < *formatCount; i++) {
|
for (int i = 0; i < *formatCount; i++) {
|
||||||
switch (vkFormats[i].format) {
|
switch (vkFormats[i].format) {
|
||||||
case VK_FORMAT_B8G8R8A8_SRGB: { formats[i].format = GN_FORMAT_BGRA8_SRGB; break; }
|
case VK_FORMAT_B8G8R8A8_SRGB: { formats[i].format = GN_FORMAT_BGRA8_SRGB; break; }
|
||||||
default: break;
|
case VK_FORMAT_B8G8R8A8_UNORM: { formats[i].format = GN_FORMAT_BGRA8; break; }
|
||||||
|
default: { formats[i].format = GN_FORMAT_NONE; break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (vkFormats[i].colorSpace) {
|
switch (vkFormats[i].colorSpace) {
|
||||||
case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR: { formats[i].colorSpace = GN_COLOR_SPACE_SRGB_NONLINEAR; break; }
|
case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR: { formats[i].colorSpace = GN_COLOR_SPACE_SRGB_NONLINEAR; break; }
|
||||||
default: break;
|
default: { formats[i].colorSpace = GN_COLOR_SPACE_NONE; break; };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,6 +113,7 @@ VkFormat vkGryphnFormatToVulkanFormat(gnImageFormat format) {
|
|||||||
switch (format) {
|
switch (format) {
|
||||||
case GN_FORMAT_NONE: return VK_FORMAT_UNDEFINED;
|
case GN_FORMAT_NONE: return VK_FORMAT_UNDEFINED;
|
||||||
case GN_FORMAT_BGRA8_SRGB: return VK_FORMAT_B8G8R8A8_SRGB;
|
case GN_FORMAT_BGRA8_SRGB: return VK_FORMAT_B8G8R8A8_SRGB;
|
||||||
|
case GN_FORMAT_BGRA8: return VK_FORMAT_B8G8R8A8_UNORM;
|
||||||
case GN_FORMAT_RGBA8_SRGB: return VK_FORMAT_R8G8B8A8_SRGB;
|
case GN_FORMAT_RGBA8_SRGB: return VK_FORMAT_R8G8B8A8_SRGB;
|
||||||
case GN_FORMAT_D32S8_UINT: return VK_FORMAT_D32_SFLOAT_S8_UINT;
|
case GN_FORMAT_D32S8_UINT: return VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||||
case GN_FORMAT_D24S8_UINT: return VK_FORMAT_D24_UNORM_S8_UINT;
|
case GN_FORMAT_D24S8_UINT: return VK_FORMAT_D24_UNORM_S8_UINT;
|
||||||
@@ -119,6 +121,7 @@ VkFormat vkGryphnFormatToVulkanFormat(gnImageFormat format) {
|
|||||||
}
|
}
|
||||||
VkColorSpaceKHR vkGryphnColorSpaceToVulkanColorSpace(gnColorSpace colorSpace) {
|
VkColorSpaceKHR vkGryphnColorSpaceToVulkanColorSpace(gnColorSpace colorSpace) {
|
||||||
switch (colorSpace) {
|
switch (colorSpace) {
|
||||||
|
case GN_COLOR_SPACE_NONE: { return VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; }; // this is a problem if we are trying to convert it
|
||||||
case GN_COLOR_SPACE_SRGB_NONLINEAR: { return VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; }
|
case GN_COLOR_SPACE_SRGB_NONLINEAR: { return VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,7 @@ CAMetalLayer* gnCreateCAMetalLayer(NSWindow* window) {
|
|||||||
[view setWantsLayer:YES];
|
[view setWantsLayer:YES];
|
||||||
CGSize viewSize = view.bounds.size;
|
CGSize viewSize = view.bounds.size;
|
||||||
CGFloat scale = window.screen.backingScaleFactor;
|
CGFloat scale = window.screen.backingScaleFactor;
|
||||||
|
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||||
layer.drawableSize = CGSizeMake(viewSize.width * scale,
|
layer.drawableSize = CGSizeMake(viewSize.width * scale,
|
||||||
viewSize.height * scale);
|
viewSize.height * scale);
|
||||||
return layer;
|
return layer;
|
||||||
@@ -41,7 +42,7 @@ void gnResizeCAMetalLayer(NSWindow* window) {
|
|||||||
CGFloat scale = window.screen.backingScaleFactor;
|
CGFloat scale = window.screen.backingScaleFactor;
|
||||||
layer.drawableSize = CGSizeMake(viewSize.width * scale,
|
layer.drawableSize = CGSizeMake(viewSize.width * scale,
|
||||||
viewSize.height * scale);
|
viewSize.height * scale);
|
||||||
|
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CAMetalLayer* gnGetCAMetalLayer(NSWindow* window) {
|
// CAMetalLayer* gnGetCAMetalLayer(NSWindow* window) {
|
||||||
|
Reference in New Issue
Block a user