metal: initial texel buffer implementation

This commit is contained in:
Alex Szpakowski
2020-07-29 19:35:45 -03:00
parent 2e4b1f5dd9
commit a8c879f3bf
2 changed files with 51 additions and 1 deletions
+3 -1
View File
@@ -42,13 +42,15 @@ public:
void setMappedRangeModified(size_t offset, size_t size) 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 0; }
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;
NSRange mappedRange;
+48
View File
@@ -27,13 +27,61 @@ namespace graphics
namespace metal
{
static MTLPixelFormat getMTLPixelFormat(DataFormat format)
{
switch (format)
{
case DATAFORMAT_FLOAT: return MTLPixelFormatR32Float;
case DATAFORMAT_FLOAT_VEC2: return MTLPixelFormatRG32Float;
case DATAFORMAT_FLOAT_VEC4: return MTLPixelFormatRGBA32Float;
case DATAFORMAT_INT32: return MTLPixelFormatR32Sint;
case DATAFORMAT_INT32_VEC2: return MTLPixelFormatRG32Sint;
case DATAFORMAT_INT32_VEC4: return MTLPixelFormatRGBA32Sint;
case DATAFORMAT_UINT32: return MTLPixelFormatR32Uint;
case DATAFORMAT_UINT32_VEC2: return MTLPixelFormatRG32Uint;
case DATAFORMAT_UINT32_VEC4: return MTLPixelFormatRGBA32Uint;
case DATAFORMAT_UNORM8_VEC4: return MTLPixelFormatRGBA8Unorm;
case DATAFORMAT_SNORM8_VEC4: return MTLPixelFormatRGBA8Snorm;
case DATAFORMAT_INT8_VEC4: return MTLPixelFormatRGBA8Sint;
case DATAFORMAT_UINT8_VEC4: return MTLPixelFormatRGBA8Uint;
case DATAFORMAT_UNORM16_VEC2: return MTLPixelFormatRG16Unorm;
case DATAFORMAT_UNORM16_VEC4: return MTLPixelFormatRGBA16Unorm;
case DATAFORMAT_INT16_VEC2: return MTLPixelFormatRG16Sint;
case DATAFORMAT_INT16_VEC4: return MTLPixelFormatRGBA16Sint;
case DATAFORMAT_UINT16: return MTLPixelFormatR16Uint;
case DATAFORMAT_UINT16_VEC2: return MTLPixelFormatRG16Uint;
case DATAFORMAT_UINT16_VEC4: return MTLPixelFormatRGBA16Uint;
default: return MTLPixelFormatInvalid;
}
}
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)
, mappedRange()
{ @autoreleasepool {
size = getSize();
arraylength = getArrayLength();
MTLResourceOptions opts = MTLResourceStorageModeManaged;
buffer = [device newBufferWithLength:size options:opts];
if (buffer == nil)
throw love::Exception("Could not create buffer (out of VRAM?)");
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 (texture == nil)
throw love::Exception("Could not create Metal texel buffer.");
}
// TODO: synchronization etc
memoryMap = (char *) buffer.contents;