Merge branch '12.0-development' into metal

This commit is contained in:
Alex Szpakowski
2020-12-22 22:37:17 -04:00
288 changed files with 15292 additions and 12550 deletions
+6 -7
View File
@@ -22,6 +22,7 @@
#include "graphics/Buffer.h"
#include "Metal.h"
#include "common/Range.h"
namespace love
{
@@ -37,23 +38,21 @@ public:
Buffer(love::graphics::Graphics *gfx, id<MTLDevice> device, const Settings &settings, const std::vector<DataDeclaration> &format, const void *data, size_t size, size_t arraylength);
virtual ~Buffer();
void *map() override;
void unmap() override;
void setMappedRangeModified(size_t offset, size_t size) override;
void *map(MapType map, size_t offset, size_t size) override;
void unmap(size_t usedoffset, size_t usedsize) override;
void fill(size_t offset, size_t size, const void *data) override;
ptrdiff_t getHandle() const override { return (ptrdiff_t) buffer; }
ptrdiff_t getTexelBufferHandle() const override { return (ptrdiff_t) texture; }
void copyTo(size_t offset, size_t size, love::graphics::Buffer *other, size_t otheroffset) override;
private:
id<MTLBuffer> buffer;
id<MTLTexture> texture;
char *memoryMap;
id<MTLBuffer> mapBuffer;
NSRange mappedRange;
Range mappedRange;
}; // Buffer
+78 -32
View File
@@ -19,6 +19,7 @@
**/
#import "Buffer.h"
#include "Graphics.h"
namespace love
{
@@ -58,12 +59,13 @@ static MTLPixelFormat getMTLPixelFormat(DataFormat format)
Buffer::Buffer(love::graphics::Graphics *gfx, id<MTLDevice> device, const Settings &settings, const std::vector<DataDeclaration> &format, const void *data, size_t size, size_t arraylength)
: love::graphics::Buffer(gfx, settings, format, size, arraylength)
, texture(nil)
, mapBuffer(nil)
, mappedRange()
{ @autoreleasepool {
size = getSize();
arraylength = getArrayLength();
MTLResourceOptions opts = MTLResourceStorageModeManaged;
MTLResourceOptions opts = MTLResourceStorageModePrivate;
buffer = [device newBufferWithLength:size options:opts];
if (buffer == nil)
@@ -71,25 +73,22 @@ Buffer::Buffer(love::graphics::Graphics *gfx, id<MTLDevice> device, const Settin
if (typeFlags & TYPEFLAG_TEXEL)
{
MTLPixelFormat pixformat = getMTLPixelFormat(getDataMember(0).decl.format);
auto desc = [MTLTextureDescriptor textureBufferDescriptorWithPixelFormat:pixformat
width:size
resourceOptions:opts
usage:MTLTextureUsageShaderRead];
texture = [buffer newTextureWithDescriptor:desc offset:0 bytesPerRow:size];
if (@available(iOS 12, macOS 10.14, *))
{
MTLPixelFormat pixformat = getMTLPixelFormat(getDataMember(0).decl.format);
auto desc = [MTLTextureDescriptor textureBufferDescriptorWithPixelFormat:pixformat
width:size
resourceOptions:opts
usage:MTLTextureUsageShaderRead];
texture = [buffer newTextureWithDescriptor:desc offset:0 bytesPerRow:size];
}
if (texture == nil)
throw love::Exception("Could not create Metal texel buffer.");
}
// TODO: synchronization etc
memoryMap = (char *) buffer.contents;
if (data != nullptr)
{
memcpy(map(), data, size);
unmap();
}
fill(0, size, data);
}}
Buffer::~Buffer()
@@ -98,30 +97,77 @@ Buffer::~Buffer()
texture = nil;
}}
void *Buffer::map()
{
return memoryMap;
}
void Buffer::unmap()
void *Buffer::map(MapType /*map*/, size_t offset, size_t size)
{ @autoreleasepool {
[buffer didModifyRange:{0, size}];
if (size == 0)
return nullptr;
Range r(offset, size);
if (!Range(0, getSize()).contains(r))
return nullptr;
auto gfx = Graphics::getInstance();
// TODO: Don't create a new buffer every time, also do something for stream
// buffers.
mapBuffer = [gfx->device newBufferWithLength:size options:MTLResourceStorageModeShared];
if (mapBuffer != nil)
{
mappedRange = r;
return mapBuffer.contents;
}
return nullptr;
}}
void Buffer::setMappedRangeModified(size_t offset, size_t size)
{
mappedRange = NSIntersectionRange(mappedRange, {offset, size});
}
void Buffer::unmap(size_t usedoffset, size_t usedsize)
{ @autoreleasepool {
if (mapBuffer == nil)
return;
Range r(usedoffset, usedsize);
if (!mapped || !mappedRange.contains(r))
return;
auto gfx = Graphics::getInstance();
auto encoder = gfx->useBlitEncoder();
[encoder copyFromBuffer:mapBuffer
sourceOffset:(usedoffset - mappedRange.getOffset())
toBuffer:buffer
destinationOffset:usedoffset
size:usedsize];
mapBuffer = nil;
}}
void Buffer::fill(size_t offset, size_t size, const void *data)
{
// TODO
}
{ @autoreleasepool {
if (size == 0)
return;
void Buffer::copyTo(size_t offset, size_t size, love::graphics::Buffer *other, size_t otheroffset)
{
// TODO
}
size_t buffersize = getSize();
if (!Range(0, buffersize).contains(Range(offset, size)))
return;
// TODO: Don't create a new buffer every time, also do something for stream
// buffers.
auto gfx = Graphics::getInstance();
auto encoder = gfx->useBlitEncoder();
auto tempbuffer = [gfx->device newBufferWithLength:size options:MTLResourceStorageModeShared];
memcpy(tempbuffer.contents, data, size);
[encoder copyFromBuffer:tempbuffer
sourceOffset:0
toBuffer:buffer
destinationOffset:offset
size:size];
}}
} // metal
} // graphics
+4 -1
View File
@@ -49,7 +49,7 @@ public:
love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength) override;
void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int backbufferdepth) override;
bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override;
void unSetMode() override;
void setActive(bool active) override;
@@ -65,6 +65,9 @@ public:
void present(void *screenshotCallbackData) override;
int getRequestedBackbufferMSAA() const override { return 0; } // TODO
int getBackbufferMSAA() const override { return 0; } // TODO
void setColor(Colorf c) override;
void setScissor(const Rect &rect) override;
+4 -3
View File
@@ -188,7 +188,8 @@ Graphics::Graphics()
{0.0f, 0.0f, 0.0f, 1.0f},
{0, 0, 0, 1},
};
Buffer::Settings attribsettings(Buffer::TYPEFLAG_VERTEX, 0, BUFFERUSAGE_STATIC);
Buffer::Settings attribsettings(Buffer::TYPEFLAG_VERTEX, BUFFERUSAGE_STATIC);
defaultAttributesBuffer = newBuffer(attribsettings, dataformat, &defaults, sizeof(DefaultVertexAttributes), 0);
}
@@ -288,13 +289,13 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh
}
}
bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int backbufferdepth)
bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa)
{ @autoreleasepool {
this->width = width;
this->height = height;
this->metalLayer = (__bridge CAMetalLayer *) context;
this->windowHasStencil = backbufferstencil;
this->windowHasStencil = windowhasstencil;
metalLayer.device = device;
metalLayer.pixelFormat = isGammaCorrect() ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm;
+2 -2
View File
@@ -40,8 +40,6 @@ public:
Texture(love::graphics::Graphics *gfx, id<MTLDevice> device, const Settings &settings, const Slices *data);
virtual ~Texture();
void generateMipmaps() override;
love::image::ImageData *newImageData(love::image::Image *module, int slice, int mipmap, const Rect &rect) override;
void setSamplerState(const SamplerState &s) override;
ptrdiff_t getHandle() const override { return (ptrdiff_t) texture; }
@@ -54,6 +52,8 @@ public:
private:
void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r, love::image::ImageDataBase *imgd = nullptr) override;
void generateMipmapsInternal() override;
void readbackImageData(love::image::ImageData *imagedata, int slice, int mipmap, const Rect &rect) override;
id<MTLTexture> texture;
id<MTLTexture> msaaTexture;
+2 -3
View File
@@ -197,7 +197,7 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s
options:options];
}}
void Texture::generateMipmaps()
void Texture::generateMipmapsInternal()
{ @autoreleasepool {
// TODO: alternate method for non-color-renderable and non-filterable
// pixel formats.
@@ -205,10 +205,9 @@ void Texture::generateMipmaps()
[encoder generateMipmapsForTexture:texture];
}}
love::image::ImageData *Texture::newImageData(love::image::Image *module, int slice, int mipmap, const Rect &rect)
void Texture::readbackImageData(love::image::ImageData *imagedata, int slice, int mipmap, const Rect &rect)
{
// TODO
return nullptr;
}
void Texture::setSamplerState(const SamplerState &s)