metal: improve newTexture performance for non-canvas textures when there's no initial data provided.

This commit is contained in:
Sasha Szpakowski
2026-07-01 14:20:25 -03:00
parent fc0cb61c6c
commit cad88c0098
+15 -8
View File
@@ -128,7 +128,6 @@ Texture::Texture(love::graphics::Graphics *gfxbase, id<MTLDevice> device, const
bool shouldgeneratemips = false; bool shouldgeneratemips = false;
std::vector<uint8> emptydata;
MTLRenderPassDescriptor *passdesc = nil; MTLRenderPassDescriptor *passdesc = nil;
// Initialize texture. // Initialize texture.
@@ -195,11 +194,12 @@ Texture::Texture(love::graphics::Graphics *gfxbase, id<MTLDevice> device, const
else if (getMSAA() <= 1 && !isPixelFormatDepthStencil(format) && !isPixelFormatCompressed(format)) else if (getMSAA() <= 1 && !isPixelFormatDepthStencil(format) && !isPixelFormatCompressed(format))
{ {
// Initialize to transparent black. // Initialize to transparent black.
if (emptydata.empty()) size_t datasize = getPixelFormatSliceSize(format, w, h);
emptydata.resize(getPixelFormatSliceSize(format, w, h));
Rect r = {0, 0, getPixelWidth(mip), getPixelHeight(mip)}; Rect r = {0, 0, getPixelWidth(mip), getPixelHeight(mip)};
uploadByteData(emptydata.data(), emptydata.size(), mip, slice, r);
// Special case: memset(0) if data is null.
// TODO: make this a more sensible part of the internal Texture API?
uploadByteData(nullptr, datasize, mip, slice, r);
} }
else else
{ {
@@ -264,9 +264,11 @@ Texture::~Texture()
void Texture::uploadByteData(const void *data, size_t size, int level, int slice, const Rect &r) void Texture::uploadByteData(const void *data, size_t size, int level, int slice, const Rect &r)
{ @autoreleasepool { { @autoreleasepool {
auto gfx = Graphics::getInstance(); auto gfx = Graphics::getInstance();
id<MTLBuffer> buffer = [gfx->device newBufferWithBytes:data
length:size id<MTLBuffer> buffer = [gfx->device newBufferWithLength:size options:MTLResourceStorageModeShared];
options:MTLResourceStorageModeShared];
if (data != nullptr)
memcpy(buffer.contents, data, size);
id<MTLBlitCommandEncoder> encoder = gfx->useBlitEncoder(); id<MTLBlitCommandEncoder> encoder = gfx->useBlitEncoder();
@@ -301,6 +303,11 @@ void Texture::uploadByteData(const void *data, size_t size, int level, int slice
// TODO: Verify this is correct for compressed formats at small sizes. // TODO: Verify this is correct for compressed formats at small sizes.
size_t sliceSize = getPixelFormatSliceSize(format, r.w, r.h); size_t sliceSize = getPixelFormatSliceSize(format, r.w, r.h);
// Special case: memset(0) if data is null.
// TODO: make this a more sensible part of the internal Texture API?
if (data == nullptr)
[encoder fillBuffer:buffer range:NSMakeRange(0, size) value:0];
[encoder copyFromBuffer:buffer [encoder copyFromBuffer:buffer
sourceOffset:0 sourceOffset:0
sourceBytesPerRow:rowSize sourceBytesPerRow:rowSize