mirror of
https://github.com/love2d/love.git
synced 2026-08-17 11:00:31 +02:00
metal: initial sampler cache implementation
This commit is contained in:
@@ -23,6 +23,8 @@
|
|||||||
#include "graphics/Graphics.h"
|
#include "graphics/Graphics.h"
|
||||||
#include "Metal.h"
|
#include "Metal.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
@class CAMetalLayer;
|
@class CAMetalLayer;
|
||||||
@protocol CAMetalDrawable;
|
@protocol CAMetalDrawable;
|
||||||
|
|
||||||
@@ -187,6 +189,8 @@ private:
|
|||||||
uint32 dirtyRenderState;
|
uint32 dirtyRenderState;
|
||||||
bool windowHasStencil;
|
bool windowHasStencil;
|
||||||
|
|
||||||
|
std::map<uint64, void *> cachedSamplers;
|
||||||
|
|
||||||
}; // Graphics
|
}; // Graphics
|
||||||
|
|
||||||
} // metal
|
} // metal
|
||||||
|
|||||||
@@ -198,6 +198,9 @@ Graphics::~Graphics()
|
|||||||
passDesc = nil;
|
passDesc = nil;
|
||||||
commandQueue = nil;
|
commandQueue = nil;
|
||||||
device = nil;
|
device = nil;
|
||||||
|
|
||||||
|
for (auto &kvp : cachedSamplers)
|
||||||
|
CFBridgingRelease(kvp.second);
|
||||||
}}
|
}}
|
||||||
|
|
||||||
love::graphics::StreamBuffer *Graphics::newStreamBuffer(BufferType type, size_t size)
|
love::graphics::StreamBuffer *Graphics::newStreamBuffer(BufferType type, size_t size)
|
||||||
@@ -393,32 +396,37 @@ void Graphics::submitBlitEncoder()
|
|||||||
|
|
||||||
id<MTLSamplerState> Graphics::getCachedSampler(const SamplerState &s)
|
id<MTLSamplerState> Graphics::getCachedSampler(const SamplerState &s)
|
||||||
{ @autoreleasepool {
|
{ @autoreleasepool {
|
||||||
id<MTLSamplerState> sampler = nil;
|
uint64 key = s.toKey();
|
||||||
|
|
||||||
{
|
auto it = cachedSamplers.find(key);
|
||||||
MTLSamplerDescriptor *desc = [MTLSamplerDescriptor new];
|
if (it != cachedSamplers.end())
|
||||||
|
return (__bridge id<MTLSamplerState>) it->second;
|
||||||
|
|
||||||
desc.minFilter = getMTLSamplerFilter(s.minFilter);
|
MTLSamplerDescriptor *desc = [MTLSamplerDescriptor new];
|
||||||
desc.magFilter = getMTLSamplerFilter(s.magFilter);
|
|
||||||
desc.mipFilter = getMTLSamplerMipFilter(s.mipmapFilter);
|
|
||||||
desc.maxAnisotropy = std::max(1.0f, std::min((float)s.maxAnisotropy, 16.0f));
|
|
||||||
|
|
||||||
desc.sAddressMode = getMTLSamplerAddressMode(s.wrapU);
|
desc.minFilter = getMTLSamplerFilter(s.minFilter);
|
||||||
desc.tAddressMode = getMTLSamplerAddressMode(s.wrapV);
|
desc.magFilter = getMTLSamplerFilter(s.magFilter);
|
||||||
desc.rAddressMode = getMTLSamplerAddressMode(s.wrapW);
|
desc.mipFilter = getMTLSamplerMipFilter(s.mipmapFilter);
|
||||||
|
desc.maxAnisotropy = std::max(1.0f, std::min((float)s.maxAnisotropy, 16.0f));
|
||||||
|
|
||||||
|
desc.sAddressMode = getMTLSamplerAddressMode(s.wrapU);
|
||||||
|
desc.tAddressMode = getMTLSamplerAddressMode(s.wrapV);
|
||||||
|
desc.rAddressMode = getMTLSamplerAddressMode(s.wrapW);
|
||||||
|
|
||||||
#ifdef LOVE_MACOS
|
#ifdef LOVE_MACOS
|
||||||
desc.borderColor = MTLSamplerBorderColorOpaqueWhite;
|
desc.borderColor = MTLSamplerBorderColorOpaqueWhite;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
desc.lodMinClamp = s.minLod;
|
desc.lodMinClamp = s.minLod;
|
||||||
desc.lodMaxClamp = s.maxLod;
|
desc.lodMaxClamp = s.maxLod;
|
||||||
|
|
||||||
if (s.depthSampleMode.hasValue)
|
if (s.depthSampleMode.hasValue)
|
||||||
desc.compareFunction = getMTLCompareFunction(s.depthSampleMode.value);
|
desc.compareFunction = getMTLCompareFunction(s.depthSampleMode.value);
|
||||||
|
|
||||||
sampler = [device newSamplerStateWithDescriptor:desc];
|
id<MTLSamplerState> sampler = [device newSamplerStateWithDescriptor:desc];
|
||||||
}
|
|
||||||
|
if (sampler != nil)
|
||||||
|
cachedSamplers[key] = (void *) CFBridgingRetain(sampler);
|
||||||
|
|
||||||
return sampler;
|
return sampler;
|
||||||
}}
|
}}
|
||||||
@@ -776,8 +784,8 @@ void Graphics::clear(OptionalColorf c, OptionalInt stencil, OptionalDouble depth
|
|||||||
// TODO: handle clearing mid-pass
|
// TODO: handle clearing mid-pass
|
||||||
if (c.hasValue)
|
if (c.hasValue)
|
||||||
{
|
{
|
||||||
MTLClearColor color = MTLClearColorMake(c.value.r, c.value.g, c.value.b, c.value.a);
|
auto color = MTLClearColorMake(c.value.r, c.value.g, c.value.b, c.value.a);
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < MAX_COLOR_RENDER_TARGETS; i++)
|
||||||
{
|
{
|
||||||
passDesc.colorAttachments[0].clearColor = color;
|
passDesc.colorAttachments[0].clearColor = color;
|
||||||
passDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
|
passDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||||
@@ -1050,7 +1058,12 @@ void Graphics::setPointSize(float size)
|
|||||||
|
|
||||||
void Graphics::setWireframe(bool enable)
|
void Graphics::setWireframe(bool enable)
|
||||||
{
|
{
|
||||||
// TODO
|
if (enable != states.back().wireframe)
|
||||||
|
{
|
||||||
|
flushBatchedDraws();
|
||||||
|
states.back().wireframe = enable;
|
||||||
|
dirtyRenderState |= STATEBIT_WIREFRAME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelFormat Graphics::getSizedFormat(PixelFormat format, bool /*rendertarget*/, bool /*readable*/, bool /*sRGB*/) const
|
PixelFormat Graphics::getSizedFormat(PixelFormat format, bool /*rendertarget*/, bool /*readable*/, bool /*sRGB*/) const
|
||||||
|
|||||||
@@ -127,6 +127,8 @@ Texture::Texture(id<MTLDevice> device, const Settings &settings, const Slices *d
|
|||||||
// so generateMipmaps here is fine - when they aren't already initialized.
|
// so generateMipmaps here is fine - when they aren't already initialized.
|
||||||
if (getMipmapCount() > 1 && (data == nullptr || data->getMipmapCount() <= 1))
|
if (getMipmapCount() > 1 && (data == nullptr || data->getMipmapCount() <= 1))
|
||||||
generateMipmaps();
|
generateMipmaps();
|
||||||
|
|
||||||
|
setSamplerState(samplerState);
|
||||||
}}
|
}}
|
||||||
|
|
||||||
Texture::~Texture()
|
Texture::~Texture()
|
||||||
@@ -206,9 +208,9 @@ love::image::ImageData *Texture::newImageData(love::image::Image *module, int sl
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Texture::setSamplerState(const SamplerState &s)
|
void Texture::setSamplerState(const SamplerState &s)
|
||||||
{
|
{ @autoreleasepool {
|
||||||
// TODO
|
sampler = Graphics::getInstance()->getCachedSampler(s);
|
||||||
}
|
}}
|
||||||
|
|
||||||
} // metal
|
} // metal
|
||||||
} // graphics
|
} // graphics
|
||||||
|
|||||||
Reference in New Issue
Block a user