metal: initial sampler cache implementation

This commit is contained in:
Alex Szpakowski
2020-04-26 09:09:26 -03:00
parent 643a046d64
commit ceb1e4459b
3 changed files with 42 additions and 23 deletions
+4
View File
@@ -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
+33 -20
View File
@@ -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
+5 -3
View File
@@ -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