From 4e1c4a6afead141c79f666df951fe2ac7016a5d9 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 16 Jan 2022 13:44:29 -0400 Subject: [PATCH] metal: some fixes for MSAA --- src/modules/graphics/metal/Graphics.h | 4 +++ src/modules/graphics/metal/Graphics.mm | 48 +++++++++++++++----------- src/modules/graphics/metal/Texture.h | 4 ++- src/modules/graphics/metal/Texture.mm | 16 +++++---- 4 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/modules/graphics/metal/Graphics.h b/src/modules/graphics/metal/Graphics.h index 7b833d63b..104bc9eab 100644 --- a/src/modules/graphics/metal/Graphics.h +++ b/src/modules/graphics/metal/Graphics.h @@ -123,6 +123,8 @@ public: id getCommandBuffer() const { return commandBuffer; } void submitCommandBuffer(SubmitType type); + void submitAllEncoders(SubmitType type); + id useRenderEncoder(); id getRenderEncoder() const { return renderEncoder; } void submitRenderEncoder(SubmitType type); @@ -141,6 +143,8 @@ public: Buffer *getDefaultAttributesBuffer() const { return defaultAttributesBuffer; } Texture *getDefaultTexture(TextureType textype) const { return defaultTextures[textype]; } + int getClosestMSAASamples(int requestedsamples); + static Graphics *getInstance() { return graphicsInstance; } id device; diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index 3691a5abd..cdbcf6f34 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -118,7 +118,7 @@ static MTLPrimitiveType getMTLPrimitiveType(PrimitiveType prim) { case PRIMITIVE_TRIANGLES: return MTLPrimitiveTypeTriangle; case PRIMITIVE_TRIANGLE_STRIP: return MTLPrimitiveTypeTriangleStrip; - case PRIMITIVE_TRIANGLE_FAN: return MTLPrimitiveTypeTriangle; // This needs to be emulated. + case PRIMITIVE_TRIANGLE_FAN: return MTLPrimitiveTypeTriangle; // TODO: This needs to be emulated. case PRIMITIVE_POINTS: return MTLPrimitiveTypePoint; case PRIMITIVE_MAX_ENUM: return MTLPrimitiveTypeTriangle; } @@ -448,7 +448,7 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh backbufferMSAA.set(nullptr); if (settings.msaa > 1) { - settings.format = isGammaCorrect() ? PIXELFORMAT_RGBA8_UNORM_sRGB : PIXELFORMAT_RGBA8_UNORM; + settings.format = isGammaCorrect() ? PIXELFORMAT_BGRA8_UNORM_sRGB : PIXELFORMAT_BGRA8_UNORM; backbufferMSAA.set(newTexture(settings), Acquire::NORETAIN); } @@ -537,9 +537,7 @@ id Graphics::useCommandBuffer() void Graphics::submitCommandBuffer(SubmitType type) { - submitRenderEncoder(type); - submitBlitEncoder(); - submitComputeEncoder(); + submitAllEncoders(type); if (commandBuffer != nil) { @@ -548,6 +546,13 @@ void Graphics::submitCommandBuffer(SubmitType type) } } +void Graphics::submitAllEncoders(SubmitType type) +{ + submitRenderEncoder(type); + submitBlitEncoder(); + submitComputeEncoder(); +} + static inline void setAttachment(const Graphics::RenderTarget &rt, MTLRenderPassAttachmentDescriptor *desc, MTLStoreAction &storeaction, bool setload = true) { bool isvolume = rt.texture->getTextureType() == TEXTURE_VOLUME; @@ -579,8 +584,7 @@ id Graphics::useRenderEncoder() { if (renderEncoder == nil) { - submitBlitEncoder(); - submitComputeEncoder(); + submitAllEncoders(SUBMIT_STORE); // Pass desc info for non-backbuffer render targets are set up in // setRenderTargetsInternal. @@ -682,8 +686,7 @@ id Graphics::useBlitEncoder() { if (blitEncoder == nil) { - submitRenderEncoder(SUBMIT_STORE); - submitComputeEncoder(); + submitAllEncoders(SUBMIT_STORE); blitEncoder = [useCommandBuffer() blitCommandEncoder]; } @@ -703,8 +706,7 @@ id Graphics::useComputeEncoder() { if (computeEncoder == nil) { - submitRenderEncoder(SUBMIT_STORE); - submitBlitEncoder(); + submitAllEncoders(SUBMIT_STORE); computeEncoder = [useCommandBuffer() computeCommandEncoder]; renderBindings = {}; } @@ -902,20 +904,26 @@ void Graphics::applyRenderState(id encoder, const Verte key.blend = state.blend; key.colorChannelMask = state.colorMask; - if (state.renderTargets.getFirstTarget().texture.get() == nullptr) + const auto &firsttarget = state.renderTargets.getFirstTarget(); + + if (firsttarget.texture.get() == nullptr) { key.colorRenderTargetFormats = isGammaCorrect() ? PIXELFORMAT_BGRA8_UNORM_sRGB : PIXELFORMAT_BGRA8_UNORM; key.depthStencilFormat = backbufferDepthStencil->getPixelFormat(); + key.msaa = backbufferMSAA ? (uint8) backbufferMSAA->getMSAA() : 1; } else { const auto &rts = state.renderTargets.colors; + for (size_t i = 0; i < rts.size(); i++) key.colorRenderTargetFormats |= (rts[i].texture->getPixelFormat()) << (8 * i); // TODO: automatic depth/stencil (state doesn't store it). if (state.renderTargets.depthStencil.texture.get()) key.depthStencilFormat = state.renderTargets.depthStencil.texture->getPixelFormat(); + + key.msaa = (uint8) firsttarget.texture->getMSAA(); } pipeline = shader->getCachedRenderPipeline(key); @@ -2052,19 +2060,19 @@ Graphics::RendererInfo Graphics::getRendererInfo() const return info; } -void Graphics::initCapabilities() +int Graphics::getClosestMSAASamples(int requestedsamples) { - int msaa = 1; const int checkmsaa[] = {32, 16, 8, 4, 2}; for (int samples : checkmsaa) { - if ([device supportsTextureSampleCount:samples]) - { - msaa = samples; - break; - } + if (samples <= requestedsamples && [device supportsTextureSampleCount:samples]) + return samples; } + return 1; +} +void Graphics::initCapabilities() +{ if (@available(macOS 10.15, iOS 13.0, *)) { for (NSInteger i = 0; i < 7; i++) @@ -2161,7 +2169,7 @@ void Graphics::initCapabilities() capabilities.limits[LIMIT_RENDER_TARGETS] = 8; else capabilities.limits[LIMIT_RENDER_TARGETS] = 4; - capabilities.limits[LIMIT_TEXTURE_MSAA] = msaa; + capabilities.limits[LIMIT_TEXTURE_MSAA] = getClosestMSAASamples(32); capabilities.limits[LIMIT_ANISOTROPY] = 16.0f; static_assert(LIMIT_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new system limit!"); diff --git a/src/modules/graphics/metal/Texture.h b/src/modules/graphics/metal/Texture.h index 56abf5d4c..5084ebc25 100644 --- a/src/modules/graphics/metal/Texture.h +++ b/src/modules/graphics/metal/Texture.h @@ -49,7 +49,7 @@ public: ptrdiff_t getRenderTargetHandle() const override { return msaaTexture != nil ? (ptrdiff_t) msaaTexture : (ptrdiff_t) texture; } ptrdiff_t getSamplerHandle() const override { return (ptrdiff_t) sampler; } - int getMSAA() const override { return 1 /* TODO*/; } + int getMSAA() const override { return actualMSAASamples; } id getMTLSampler() const { return sampler; } @@ -63,6 +63,8 @@ private: id msaaTexture; id sampler; + int actualMSAASamples; + }; // Texture } // metal diff --git a/src/modules/graphics/metal/Texture.mm b/src/modules/graphics/metal/Texture.mm index fcad6a800..9fa7aa6d4 100644 --- a/src/modules/graphics/metal/Texture.mm +++ b/src/modules/graphics/metal/Texture.mm @@ -41,12 +41,15 @@ static MTLTextureType getMTLTextureType(TextureType type, int msaa) return MTLTextureType2D; } -Texture::Texture(love::graphics::Graphics *gfx, id device, const Settings &settings, const Slices *data) - : love::graphics::Texture(gfx, settings, data) +Texture::Texture(love::graphics::Graphics *gfxbase, id device, const Settings &settings, const Slices *data) + : love::graphics::Texture(gfxbase, settings, data) , texture(nil) , msaaTexture(nil) , sampler(nil) + , actualMSAASamples(1) { @autoreleasepool { + auto gfx = (Graphics *) gfxbase; + MTLTextureDescriptor *desc = [MTLTextureDescriptor new]; int w = pixelWidth; @@ -81,11 +84,12 @@ Texture::Texture(love::graphics::Graphics *gfx, id device, const Sett if (texture == nil) throw love::Exception("Out of graphics memory."); - if (getRequestedMSAA() > 1) + actualMSAASamples = gfx->getClosestMSAASamples(getRequestedMSAA()); + + if (actualMSAASamples > 1) { - // TODO: sampleCount validation - desc.sampleCount = getRequestedMSAA(); - desc.textureType = getMTLTextureType(texType, (int)desc.sampleCount); + desc.sampleCount = actualMSAASamples; + desc.textureType = getMTLTextureType(texType, actualMSAASamples); desc.usage &= ~MTLTextureUsageShaderRead; // TODO: This needs to be cleared, etc.