Add Metal support for Texture::import (#2782)
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user