Add Metal support for Texture::import (#2782)

This commit is contained in:
Ben Doherty
2020-07-09 10:39:22 -07:00
committed by GitHub
parent 07e4d1c148
commit 3c1ea07502
5 changed files with 78 additions and 1 deletions

View File

@@ -177,10 +177,30 @@ void MetalDriver::createTextureSwizzledR(Handle<HwTexture> th, SamplerType targe
// TODO: implement texture swizzle
}
void MetalDriver::importTextureR(Handle<HwTexture> th, intptr_t id,
void MetalDriver::importTextureR(Handle<HwTexture> th, intptr_t i,
SamplerType target, uint8_t levels,
TextureFormat format, uint8_t samples, uint32_t width, uint32_t height,
uint32_t depth, TextureUsage usage) {
id<MTLTexture> metalTexture = (id<MTLTexture>) CFBridgingRelease((void*) i);
ASSERT_PRECONDITION(metalTexture.width == width,
"Imported id<MTLTexture> width (%d) != Filament texture width (%d)",
metalTexture.width, width);
ASSERT_PRECONDITION(metalTexture.height == height,
"Imported id<MTLTexture> height (%d) != Filament texture height (%d)",
metalTexture.height, height);
ASSERT_PRECONDITION(metalTexture.mipmapLevelCount == levels,
"Imported id<MTLTexture> levels (%d) != Filament texture levels (%d)",
metalTexture.mipmapLevelCount, levels);
MTLPixelFormat filamentMetalFormat = getMetalFormat(format);
ASSERT_PRECONDITION(metalTexture.pixelFormat == filamentMetalFormat,
"Imported id<MTLTexture> format (%d) != Filament texture format (%d)",
metalTexture.pixelFormat, filamentMetalFormat);
MTLTextureType filamentMetalType = getMetalType(target);
ASSERT_PRECONDITION(metalTexture.textureType == filamentMetalType,
"Imported id<MTLTexture> type (%d) != Filament texture type (%d)",
metalTexture.textureType, filamentMetalType);
construct_handle<MetalTexture>(mHandleMap, th, *mContext, target, levels, format, samples,
width, height, depth, usage, metalTexture);
}
void MetalDriver::createSamplerGroupR(Handle<HwSamplerGroup> sbh, size_t size) {

View File

@@ -291,6 +291,20 @@ inline MTLPixelFormat getMetalFormat(TextureFormat format) noexcept {
}
}
constexpr inline MTLTextureType getMetalType(SamplerType target) {
switch (target) {
case SamplerType::SAMPLER_2D:
case SamplerType::SAMPLER_EXTERNAL:
return MTLTextureType2D;
case SamplerType::SAMPLER_2D_ARRAY:
return MTLTextureType2DArray;
case SamplerType::SAMPLER_CUBEMAP:
return MTLTextureTypeCube;
case SamplerType::SAMPLER_3D:
return MTLTextureType3D;
}
}
constexpr inline MTLBlendOperation getMetalBlendOperation(BlendEquation equation) noexcept {
switch (equation) {
case BlendEquation::ADD: return MTLBlendOperationAdd;

View File

@@ -121,6 +121,12 @@ struct MetalTexture : public HwTexture {
MetalTexture(MetalContext& context, SamplerType target, uint8_t levels, TextureFormat format,
uint8_t samples, uint32_t width, uint32_t height, uint32_t depth, TextureUsage usage)
noexcept;
// Constructor for importing an id<MTLTexture> outside of Filament.
MetalTexture(MetalContext& context, SamplerType target, uint8_t levels, TextureFormat format,
uint8_t samples, uint32_t width, uint32_t height, uint32_t depth, TextureUsage usage,
id<MTLTexture> texture) noexcept;
~MetalTexture();
void load2DImage(uint32_t level, uint32_t xoffset, uint32_t yoffset, uint32_t width,

View File

@@ -319,6 +319,16 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le
}
}
MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t levels, TextureFormat format,
uint8_t samples, uint32_t width, uint32_t height, uint32_t depth, TextureUsage usage,
id<MTLTexture> metalTexture) noexcept
: HwTexture(target, levels, samples, width, height, depth, format, usage), context(context),
externalImage(context), reshaper(format) {
texture = metalTexture;
minLod = 0;
maxLod = levels - 1;
}
MetalTexture::~MetalTexture() {
externalImage.set(nullptr);
}

View File

@@ -201,6 +201,33 @@ public:
/* no user serviceable parts below */
/**
* Specify a native texture to import as a Filament texture.
*
* The texture id is backend-specific:
* - OpenGL: GLuint texture ID
* - Metal: id<MTLTexture>
*
* With Metal, the id<MTLTexture> object should be cast to an intptr_t using
* CFBridgingRetain to transfer ownership to Filament. Filament will release ownership of
* the textue object when the Filament texture is destroyed.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
* id <MTLTexture> metalTexture = ...
* filamentTexture->import((intptr_t) CFBridgingRetain(metalTexture));
* // free to release metalTexture
*
* // after using texture:
* engine->destroy(filamentTexture); // metalTexture is released
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @warning This method should be used as a last resort. This API is subject to change or
* removal.
*
* @param id a backend specific texture identifier
*
* @return This Builder, for chaining calls.
*/
Builder& import(intptr_t id) noexcept;
private: