Implement Metal texture swizzling (#3720)
This commit is contained in:
@@ -176,7 +176,8 @@ void MetalDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint8
|
||||
TextureFormat format, uint8_t samples, uint32_t width, uint32_t height,
|
||||
uint32_t depth, TextureUsage usage) {
|
||||
construct_handle<MetalTexture>(mHandleMap, th, *mContext, target, levels, format, samples,
|
||||
width, height, depth, usage);
|
||||
width, height, depth, usage, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1,
|
||||
TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_3);
|
||||
}
|
||||
|
||||
void MetalDriver::createTextureSwizzledR(Handle<HwTexture> th, SamplerType target, uint8_t levels,
|
||||
@@ -184,8 +185,7 @@ void MetalDriver::createTextureSwizzledR(Handle<HwTexture> th, SamplerType targe
|
||||
uint32_t depth, TextureUsage usage,
|
||||
TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, TextureSwizzle a) {
|
||||
construct_handle<MetalTexture>(mHandleMap, th, *mContext, target, levels, format, samples,
|
||||
width, height, depth, usage);
|
||||
// TODO: implement texture swizzle
|
||||
width, height, depth, usage, r, g, b, a);
|
||||
}
|
||||
|
||||
void MetalDriver::importTextureR(Handle<HwTexture> th, intptr_t i,
|
||||
@@ -551,7 +551,11 @@ bool MetalDriver::isTextureFormatSupported(TextureFormat format) {
|
||||
}
|
||||
|
||||
bool MetalDriver::isTextureSwizzleSupported() {
|
||||
return false;
|
||||
if (@available(macOS 10.15, iOS 13, *)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MetalDriver::isTextureFormatMipmappable(TextureFormat format) {
|
||||
|
||||
@@ -419,6 +419,31 @@ constexpr inline MTLCompareFunction getCompareFunction(SamplerCompareFunc compar
|
||||
}
|
||||
}
|
||||
|
||||
API_AVAILABLE(macos(10.15), ios(13.0))
|
||||
MTLTextureSwizzle getSwizzle(TextureSwizzle swizzle) {
|
||||
switch (swizzle) {
|
||||
case TextureSwizzle::SUBSTITUTE_ZERO:
|
||||
return MTLTextureSwizzleZero;
|
||||
case TextureSwizzle::SUBSTITUTE_ONE:
|
||||
return MTLTextureSwizzleOne;
|
||||
case TextureSwizzle::CHANNEL_0:
|
||||
return MTLTextureSwizzleRed;
|
||||
case TextureSwizzle::CHANNEL_1:
|
||||
return MTLTextureSwizzleGreen;
|
||||
case TextureSwizzle::CHANNEL_2:
|
||||
return MTLTextureSwizzleBlue;
|
||||
case TextureSwizzle::CHANNEL_3:
|
||||
return MTLTextureSwizzleAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
API_AVAILABLE(macos(10.15), ios(13.0))
|
||||
MTLTextureSwizzleChannels getSwizzleChannels(TextureSwizzle r, TextureSwizzle g, TextureSwizzle b,
|
||||
TextureSwizzle a) {
|
||||
return MTLTextureSwizzleChannelsMake(getSwizzle(r), getSwizzle(g), getSwizzle(b),
|
||||
getSwizzle(a));
|
||||
}
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -158,7 +158,8 @@ struct MetalProgram : public HwProgram {
|
||||
|
||||
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)
|
||||
uint8_t samples, uint32_t width, uint32_t height, uint32_t depth, TextureUsage usage,
|
||||
TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, TextureSwizzle a)
|
||||
noexcept;
|
||||
|
||||
// Constructor for importing an id<MTLTexture> outside of Filament.
|
||||
|
||||
@@ -416,7 +416,8 @@ static MTLPixelFormat decidePixelFormat(id<MTLDevice> device, TextureFormat form
|
||||
|
||||
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) noexcept
|
||||
TextureUsage usage, TextureSwizzle r, TextureSwizzle g, TextureSwizzle b,
|
||||
TextureSwizzle a) noexcept
|
||||
: HwTexture(target, levels, samples, width, height, depth, format, usage), context(context),
|
||||
externalImage(context), reshaper(format) {
|
||||
|
||||
@@ -467,6 +468,12 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le
|
||||
}
|
||||
};
|
||||
|
||||
auto setUpSwizzle = [r, g, b, a](MTLTextureDescriptor* descriptor) {
|
||||
if (@available(macOS 10.15, iOS 13, *)) {
|
||||
descriptor.swizzle = getSwizzleChannels(r, g, b, a);
|
||||
}
|
||||
};
|
||||
|
||||
MTLTextureDescriptor* descriptor;
|
||||
switch (target) {
|
||||
case SamplerType::SAMPLER_2D:
|
||||
@@ -481,6 +488,7 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le
|
||||
descriptor.sampleCount = multisampled ? samples : 1;
|
||||
descriptor.usage = getMetalTextureUsage(usage);
|
||||
descriptor.storageMode = MTLStorageModePrivate;
|
||||
setUpSwizzle(descriptor);
|
||||
texture = [context.device newTextureWithDescriptor:descriptor];
|
||||
ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?");
|
||||
break;
|
||||
@@ -493,6 +501,7 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le
|
||||
descriptor.mipmapLevelCount = levels;
|
||||
descriptor.usage = getMetalTextureUsage(usage);
|
||||
descriptor.storageMode = MTLStorageModePrivate;
|
||||
setUpSwizzle(descriptor);
|
||||
texture = [context.device newTextureWithDescriptor:descriptor];
|
||||
ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?");
|
||||
break;
|
||||
@@ -506,6 +515,7 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le
|
||||
descriptor.mipmapLevelCount = levels;
|
||||
descriptor.usage = getMetalTextureUsage(usage);
|
||||
descriptor.storageMode = MTLStorageModePrivate;
|
||||
setUpSwizzle(descriptor);
|
||||
texture = [context.device newTextureWithDescriptor:descriptor];
|
||||
ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?");
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user